calling binding() within a module method (for mixin)?????

B

Ben

I've been trying to write a method that can dynamically mixin a module
to a class. I tried the following code:
#=========================================
module MixinUtils
def MixinUtils.includeMixin(className,mixinName,vars)
evalStr= <<-END
class #{className.to_s}
include #{mixinName.to_s}
end
END
eval(evalStr, vars)
end
end

module Foo
def printFoo
puts "foo"
end
end

class Array
def someMethod
self.each do |item|
MixinUtils.includeMixin(item.class.to_s,"Foo",binding)
item.printFoo
end
end
end

[1,2,3].someMethod
#======================================

But running this gives

question.rb:22:in `something': undefined method `printFoo' for
1:Fixnum (NoMethodError)
from question.rb:20:in `each'
from question.rb:20:in `something'
from question.rb:31

But if I take out the '[1,nil,true].something' and append

a=1
MixinUtils.includeMixin("Fixnum","Foo",binding)
a.printFoo

it produces

foo

as expected. Why the difference? Why does calling 'binding' inside a
block produce different results? Thanks in advance...

Ben
 
T

ts

B> eval(evalStr, vars)

eval is evil

B> end

write it like this

B> MixinUtils.includeMixin(item.class.to_s,"Foo",binding)
B> item.printFoo

Array::Fixnum.new.printFoo

B> end



Guy Decoux
 
P

Pit Capitain

Ben said:
I've been trying to write a method that can dynamically mixin a module
to a class. I tried the following code:
(... code using eval ...)

Hi Ben,

in order to avoid eval as Guy suggested, you could try

module MixinUtils
def self.includeMixin(klass, mixin)
klass.send:)include, mixin) # include is a private method
end
end

module Foo
def printFoo
puts "foo"
end
end

class Array
def someMethod
self.each do |item|
MixinUtils.includeMixin(item.class, Foo)
item.printFoo
end
end
end

Calling

[1,nil,true].someMethod

results in

foo
foo
foo

as you expected.

Regards,
Pit
 
B

Ben

Pit Capitain said:
Ben said:
I've been trying to write a method that can dynamically mixin a module
to a class. I tried the following code:
(... code using eval ...)

Hi Ben,

in order to avoid eval as Guy suggested, you could try

module MixinUtils
def self.includeMixin(klass, mixin)
klass.send:)include, mixin) # include is a private method
end
end

module Foo
def printFoo
puts "foo"
end
end

class Array
def someMethod
self.each do |item|
MixinUtils.includeMixin(item.class, Foo)
item.printFoo
end
end
end

Calling

[1,nil,true].someMethod

results in

foo
foo
foo

as you expected.

Regards,
Pit

I'll try this out. Thanks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top