From: MonkeeSage Date: 2007-12-26T06:35:08+09:00 Subject: Re: module_eval differences between 1.8 & 1.9 On Dec 23, 8:40 am, Frederick Cheung wrote: > Consider the following: > > module Foo > end > > def do_stuff_to_foo(&block) > Foo.module_eval &block > end > > In ruby 1.8 you can do something like this > > do_stuff_to_foo {def greeting; 'hello'; end} > Foo.instance_methods #=> ['hello'] > > In ruby 1.9 however, no method is added to Foo, instead the method is > added to whoever called do_stuff_to_foo: > > do_stuff_to_foo {def greeting; 'hello'; end} > Foo.instance_methods #=> [] > greeting #=> 'hello' > > Of course if you do > Foo.module_eval {def greeting; 'hello'; end} > then the method is added to Foo on both 1.8 & 1.9 > > I had a look throughhttp://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9 > but I didn't see anything that seemed relevant. > Is this intended? Is there a way to write the do_stuff_to_foo method > in ruby 1.9 ? > > Thanks, > > Fred Played with this a bit today. It seems that #module_eval creates a private instance method *and* a class method on module Foo, and also creates a private instance method on main. And, as you noted, the method is not listed under #instance_methods (or #private_instance_methods for that matter; it's listed in #private_methods). This seems really wrong to me (at the very least, the block version should be consistent with the string version). Here is the example, expanded to demonstrate what I'm referring to: module Foo; end class Bar; include Foo; end def do_stuff_to_foo(&b) Foo.module_eval &b end do_stuff_to_foo {def greet; "hello"; end} p Foo.send(:greet) # => "hello" p Bar.send(:greet) # => "hello" p Bar.new.send(:greet) # => "hello" p self.private_methods.include? :greet # => true Ps. #module_exec is also broken like this. Regards, Jordan