[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

module_eval differences between 1.8 & 1.9

Frederick Cheung

12/23/2007 2:40:00 PM

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+i...
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

6 Answers

Frederick Cheung

12/23/2007 2:46:00 PM

0


On 23 Dec 2007, at 14:40, 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']
That should of course say
Foo.instance_methods #=> ["greeting"]
Sorry for the noise

Fred

MonkeeSage

12/24/2007 10:13:00 PM

0

On Dec 23, 8:40 am, Frederick Cheung <frederick.che...@gmail.com>
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+i...
> 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

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

MonkeeSage

12/25/2007 9:31:00 PM

0

On Dec 23, 8:40 am, Frederick Cheung <frederick.che...@gmail.com>
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+i...
> 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

Frederick Cheung

12/25/2007 9:49:00 PM

0


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

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


MonkeeSage

12/25/2007 10:40:00 PM

0

On Dec 25, 3:49 pm, Frederick Cheung <frederick.che...@gmail.com>
wrote:
> 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
>
> > 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

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... ;) Good to know it's being worked on.

Regards,
Jordan

Michael Black

2/20/2014 7:52:00 PM

0