# Module\_eval differences between 1.8 & 1.9

**URL:** <https://www.ruby-forum.com/t/module-eval-differences-between-1-8-1-9/124017>\
**Category:** Ruby\
**Created:** [December 23, 2007, 3:40pm UTC](https://www.ruby-forum.com/t/module-eval-differences-between-1-8-1-9/124017 "2007-12-23T15:40:58Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![fcheung](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/90db22/32.png) [@fcheung](https://www.ruby-forum.com/u/fcheung)\
**Post date:** [December 23, 2007, 3:40pm UTC](https://www.ruby-forum.com/t/module-eval-differences-between-1-8-1-9/124017/1 "2007-12-23T15:40:58Z")

</div>

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 [eigenclass.org](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

---

<div class="post-metadata">

**Author:** ![fcheung](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/90db22/32.png) [@fcheung](https://www.ruby-forum.com/u/fcheung)\
**Post date:** [December 23, 2007, 3:47pm UTC](https://www.ruby-forum.com/t/module-eval-differences-between-1-8-1-9/124017/2 "2007-12-23T15:47:24Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![fcheung](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/90db22/32.png) [@fcheung](https://www.ruby-forum.com/u/fcheung)\
**Post date:** [December 24, 2007, 11:15pm UTC](https://www.ruby-forum.com/t/module-eval-differences-between-1-8-1-9/124017/3 "2007-12-24T23:15:57Z")

</div>

On Dec 23, 8:40 am, Frederick C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
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

---

<div class="post-metadata">

**Author:** ![fcheung](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/90db22/32.png) [@fcheung](https://www.ruby-forum.com/u/fcheung)\
**Post date:** [December 25, 2007, 10:36pm UTC](https://www.ruby-forum.com/t/module-eval-differences-between-1-8-1-9/124017/4 "2007-12-25T22:36:42Z")

</div>

On Dec 23, 8:40 am, Frederick C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
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

---

<div class="post-metadata">

**Author:** ![fcheung](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/90db22/32.png) [@fcheung](https://www.ruby-forum.com/u/fcheung)\
**Post date:** [December 25, 2007, 10:49pm UTC](https://www.ruby-forum.com/t/module-eval-differences-between-1-8-1-9/124017/5 "2007-12-25T22:49:35Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![fcheung](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/90db22/32.png) [@fcheung](https://www.ruby-forum.com/u/fcheung)\
**Post date:** [December 25, 2007, 11:40pm UTC](https://www.ruby-forum.com/t/module-eval-differences-between-1-8-1-9/124017/6 "2007-12-25T23:40:29Z")

</div>

On Dec 25, 3:49 pm, Frederick C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
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… 😉 Good to know it’s being worked on.

Regards,  
Jordan
