From: Intransition on 19 Jun 2010 17:10 I am confused by the difference between using module_eval on a module, vs. using eval on a binding extracted from a module. Have a look at this gist: http://gist.github.com/445263 When run, it produces: s2::X uninitialized constant #<S:0x7fa6256160e8>::X s3::X uninitialized constant #<S:0x7fa625615698>::X Other than the lack of a local scope (which is not being used), why is s1 and s2 behaving differently? I would expect the results to be equivalent. And even more confusing to me, how is it that s3 can see s2's method definitions even though it's a whole new module!? Note the 'extend self' doesn't seem to make much of a difference. Take it out and s1.x is no longer accessible as would be expected. But s2 and s3 seem unaffected.
From: Brian Candler on 21 Jun 2010 06:41 Thomas Sawyer wrote: > I am confused by the difference between using module_eval on a module, > vs. using eval on a binding extracted from a module. > > Have a look at this gist: > > http://gist.github.com/445263 This looks rather odd to me: (1) you are subclassing Module, (2) you are creating instances of [this subclass of] Module, and (3) you are extending each instance of this class/module with itself. These seem to be unusual things to do, although I'm sure you have a good reason. If I rewrite the code to avoid this usage, it all looks OK: # Sample 1 module M1 def self.__binding__ @binding ||= binding end end M1.module_eval <<-END X = 10 def self.x; 10; end END raise unless M1.x == 10 rescue puts "M1.x " + $! raise unless M1::X == 10 rescue puts "M1::X " + $! # Sample 2 module M2 def self.__binding__ @binding ||= binding end end eval(<<-END, M2.__binding__) X = 10 def self.x; 10; end def self.y; 20; end END raise unless M2.x == 10 rescue puts "M2.x " + $! raise unless M2.y == 20 rescue puts "M2.y " + $! raise unless M2::X == 10 rescue puts "M2::X " + $! My simplistic understanding is that there are two sorts of object context in Ruby: the "current object", which is visible as 'self', and the "current class", which is pretty well hidden but it's where 'def' defines new instance methods, and is set by 'class' and 'class_eval'. class C end C.send(:class_eval) do def foo puts "In foo" end end C.foo rescue puts "foo is not a class method" C.new.foo C.send(:instance_eval) do def bar puts "In bar" end end C.bar C.new.bar rescue puts "bar is not an instance method" However I don't understand this fully, because I can't see how your code manages to define singleton methods on s2, just by using eval and a binding. If I try a simpler example, it doesn't: eval(<<EOS, C.send(:binding)) def baz puts "In baz" end EOS baz C.baz rescue puts "baz is private global method" C.new.baz rescue puts "baz is not an instance method" -- Posted via http://www.ruby-forum.com/.
|
Pages: 1 Prev: [QUIZ] Random Points within a Circle (#234) Next: [ANN] RubyKaigi 2010 open for registration |