From: "David A. Black" Date: 2008-08-31T16:42:48+09:00 Subject: Re: instance_eval/class_eval including/extending modules HI -- On Sun, 31 Aug 2008, Pedro Silva wrote: > Consider the following example: > > module SomeModule > def some_method > puts "Some Method - #{self}" > end > end > > class SomeClass > def self.metaclass > class << self; self; end > end > end > > SomeClass.instance_eval {include SomeModule} # instance method > SomeClass.instance_eval {extend SomeModule} # singleton method (class > method) > SomeClass.metaclass.instance_eval {include SomeModule} # class method > > Using instance_eval on SomeClass sets the "ghost class" to be the > current class, so using include shouldn't put the methods on "ghost > class" instead of SomeClass (SomeClass class methods)? In this case > using instance_eval or class_eval has the same result, depending only if > we're using include or extend. I'm not sure what you mean by "ghost class". I think that might be an unnecessary extra term. > AFAIK the "problem" has to do with value of self, because private > methods are invoked on self (default receiver), so using instance_eval > or class_eval won't matter as self will be SomeClass in both cases. > That's why calling include in instance_eval/class_eval on metaclass > (self is now the "ghost class") is the same as using extend when self is > SomeClass. That's true all the time: mixing a module into an object's singleton class is the same as extending the object with that module. In both cases, the module gets inserted in the object's method lookup path between the singleton class and the original class. > I'm using Ruby 1.8.6 and at least to me this seems kind of a strange > behaviour because using def or define_method will have different results > if we use instance_eval. Does Ruby 1.9 maintains this behaviour? Yes, and that's really part of the point of having both instance_eval and class_eval. I don't think there's any advantage to merging them into one behavior. Just choose the one you need in a given case. > In my humble opinion would make more sense if instance_eval/class_eval > maintain the same behaviour on all methods and not the "special" > behaviour on private methods. Can someone enlight me? I don't really see the anomaly you're seeing, but let me outline the rules that are followed (which, in the case of instance_eval, have nothing to do with whether or not the object is a class), and maybe that will clear it up or at least simplify it. obj.instance_eval {...} sets self to obj during the block. Instance methods defined in the block are singleton methods of obj (i.e., instance methods of obj's singleton class). c.class_eval sets self to c during the block. Instance methods defined in the block are instance methods of c. I think everything you're seeing can be accounted for by those rules. David -- Rails training from David A. Black and Ruby Power and Light: Intro to Ruby on Rails January 12-15 Fort Lauderdale, FL Advancing with Rails January 19-22 Fort Lauderdale, FL * * Co-taught with Patrick Ewing! See http://www.rubypal.com for details and updates!