Module_eval differences between 1.8 & 1.9

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 through http://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

On 23 Dec 2007, at 14:40, Frederick C. wrote:

do_stuff_to_foo {def greeting; ‘hello’; end}
Foo.instance_methods #=> [‘hello’]
That should of course say
Foo.instance_methods #=> [“greeting”]
Sorry for the noise

Fred

On Dec 23, 8:40 am, Frederick C. [email protected]
wrote:

Of course if you do
Fred
Apparently it only applies to the block version of #module_eval, the
string version seems to still work the same in 1.9.

module Foo; end
def do_stuff_to_foo(str)
Foo.module_eval str
end
do_stuff_to_foo %{def greeting; ‘hello’; end}
p Foo.instance_methods #=> [:greeting]

Not sure why there’s a difference in the block version.

Regards,
Jordan

On Dec 23, 8:40 am, Frederick C. [email protected]
wrote:

Of course if you do
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

On 25 Dec 2007, at 21:35, MonkeeSage wrote:

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).

The private method stuff is a red herring - that’s how things get
added to the top level.
Over on ruby-core Sasada Koichi said that he would fix it.

Fred

On Dec 25, 3:49 pm, Frederick C. [email protected]
wrote:

The private method stuff is a red herring - that’s how things get

def do_stuff_to_foo(&b)
Ps. #module_exec is also broken like this.

Regards,
Jordan

I didn’t know that 1.9 had started making methods defined on main
private (not that it matters). Now if they will stop being randomly
added to main regardless of with what level of visibility, and
instance methods won’t be turned into class methods, and so
forth… :wink: Good to know it’s being worked on.

Regards,
Jordan

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs