# Eval behaves differently inside a method definition

**URL:** <https://www.ruby-forum.com/t/eval-behaves-differently-inside-a-method-definition/179234>\
**Category:** Ruby\
**Created:** [November 20, 2009, 6:05am UTC](https://www.ruby-forum.com/t/eval-behaves-differently-inside-a-method-definition/179234 "2009-11-20T06:05:53Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![timr](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/3e96dc/32.png) [@timr](https://www.ruby-forum.com/u/timr)\
**Post date:** [November 20, 2009, 6:05am UTC](https://www.ruby-forum.com/t/eval-behaves-differently-inside-a-method-definition/179234/1 "2009-11-20T06:05:53Z")

</div>

#lets give strings the ability to evaluate theirselves as if in irb.

> > class String  
> > def irb  
> > eval self  
> > end  
> > end  
> > =\> nil
> 
> > “puts ‘look at me’”  
> > =\> “puts ‘look at me’”
> 
> > “puts ‘look at me’”.irb  
> > look at me  
> > =\> nil

#good looks like strings can interpret theirselves. But how about this  
case?

> > “class Pumpkin;def pie;puts ‘yum’;end;end”.irb  
> > =\> nil
> 
> > Pumpkin.new  
> > NameError: uninitialized constant Pumpkin  
> > from (irb):287  
> > from /usr/local/bin/irb:12:in `’

#not flying. Is it a problem with the string? Try with eval of the  
same string:

> > eval “class Pumpkin;def pie;puts ‘yum’;end;end”  
> > =\> nil
> 
> > Pumpkin.new  
> > =\> #Pumpkin:0x109896c

No problem evaluating the class definition in a string. So eval  
behaves differently inside a method definition.

Could anyone please explain that?  
Thanks in advance,  
Tim

---

<div class="post-metadata">

**Author:** ![timr](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/3e96dc/32.png) [@timr](https://www.ruby-forum.com/u/timr)\
**Post date:** [November 20, 2009, 6:25am UTC](https://www.ruby-forum.com/t/eval-behaves-differently-inside-a-method-definition/179234/2 "2009-11-20T06:25:46Z")

</div>

Hi Tim.

> look at me  
> from /usr/local/bin/irb:12:in `’  
> behaves differently inside a method definition.  
> It’s not that eval behaves differently inside a method definition. It’s  
> just that it takes into account the scope in which it was called.

When inside the String class, or any other class for that matter, if you  
create another class, you can’t call it from outside the parent class  
without referring to the parent. So for example:

class String  
class Pumpkin  
def pie  
puts ‘yum’  
end  
end  
end  
Pumpkin.new #=\> NameError: uninitialized constant Pumpkin  
String::Pumpkin.new #=\> #Pumpkin:0x109896c

The parent class effectively acts as a namespace for the subclass. BTW,  
I really don’t think I should call it a “subclass”, as that seems to  
imply inheritence - none of that here. Maybe someone else can tell us  
the proper name for this structure/pattern.

So you probably understand the issue by now, eval within the String  
class (whether or not inside a method definition) creates a “subclass”  
of sorts, and hence you can’t call it directly outside. If you tried to  
call “String::Pumpkin.new” instead after using your “irb” method, it  
would have worked (try it out). Alternately, you could have done it this  
way:

class String  
def irb  
eval self  
end  
end  
“class ::Pumpkin;def pie;puts ‘yum’;end;end”.irb  
Pumpkin.new.pie

Hope that helps.

- Ehsan

---

<div class="post-metadata">

**Author:** ![timr](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/3e96dc/32.png) [@timr](https://www.ruby-forum.com/u/timr)\
**Post date:** [November 20, 2009, 8:00am UTC](https://www.ruby-forum.com/t/eval-behaves-differently-inside-a-method-definition/179234/3 "2009-11-20T08:00:36Z")

</div>

> The parent class effectively acts as a namespace for the subclass. BTW, I really don’t think I should call it a “subclass”, as that seems to imply inheritence - none of that here. Maybe someone else can tell us the proper name for this structure/pattern.

I understand–how about nested class or encapsulated class.

> Hope that helps.
> 
> - Ehsan

Ehsan, nice explanation!  
Hmmm. That means that you could make a binding to main

> > SPECIAL\_BINDING = binding  
> > and add that to the eval argument to get it back to the main scope  
> > where eval seems to work on anything:

class String  
def irb  
eval(self, SPECIAL\_BINDING)  
end  
end

Now it should all work!

> > “puts ‘yohoo’”  
> > =\> “puts ‘yohoo’”
> 
> > “puts ‘yohoo’”.irb  
> > yohoo  
> > =\> nil
> 
> > “class What;def cool;puts ‘is totally awesome’;end;end”.irb  
> > =\> nil
> 
> > What.new  
> > =\> #What:0x1032a7c
> 
> > What.new.cool  
> > is totally awesome  
> > =\> nil
> 
> >

Mucho Gracias, amigo!!!  
Tim

---

<div class="post-metadata">

**Author:** ![timr](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/3e96dc/32.png) [@timr](https://www.ruby-forum.com/u/timr)\
**Post date:** [November 20, 2009, 10:33am UTC](https://www.ruby-forum.com/t/eval-behaves-differently-inside-a-method-definition/179234/4 "2009-11-20T10:33:04Z")

</div>

There is the existing TOPLEVEL\_BINDING constant you can use for this.

> > class String; def irb; eval self, TOPLEVEL\_BINDING; end; end  
> > =\> nil
> 
> > “class Pumpkin;def pie;puts ‘yum’;end;end”.irb  
> > =\> nil
> 
> > Pumpkin.new.pie  
> > yum  
> > =\> nil
> 
> >

---

<div class="post-metadata">

**Author:** ![timr](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/3e96dc/32.png) [@timr](https://www.ruby-forum.com/u/timr)\
**Post date:** [November 21, 2009, 12:25pm UTC](https://www.ruby-forum.com/t/eval-behaves-differently-inside-a-method-definition/179234/5 "2009-11-21T12:25:58Z")

</div>

Thank you Brian. Even better.
