# What's the diff between puts y and puts "#{y}" in class\_eval

**URL:** <https://www.ruby-forum.com/t/whats-the-diff-between-puts-y-and-puts-y-in-class-eval/127320>\
**Category:** Ruby\
**Created:** [January 28, 2008, 8:22am UTC](https://www.ruby-forum.com/t/whats-the-diff-between-puts-y-and-puts-y-in-class-eval/127320 "2008-01-28T08:22:36Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![dorelal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/3da27b/32.png) [@dorelal](https://www.ruby-forum.com/u/dorelal)\
**Post date:** [January 28, 2008, 8:22am UTC](https://www.ruby-forum.com/t/whats-the-diff-between-puts-y-and-puts-y-in-class-eval/127320/1 "2008-01-28T08:22:36Z")

</div>

Look at the code.

y = " another hi"

class Wes  
end

Wes.class\_eval \<\<-END  
def hello  
puts “#{y}”  
puts y # I get wrong number of arguments error  
end  
END

While puts “#{y}” works puts y fails. And I am not sure what’s the  
explanation.

Any thoughts.

---

<div class="post-metadata">

**Author:** ![dorelal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/3da27b/32.png) [@dorelal](https://www.ruby-forum.com/u/dorelal)\
**Post date:** [January 28, 2008, 8:28am UTC](https://www.ruby-forum.com/t/whats-the-diff-between-puts-y-and-puts-y-in-class-eval/127320/2 "2008-01-28T08:28:58Z")

</div>

Hi,

In message “Re: what’s the diff between puts y and puts “#{y}” in  
class\_eval”  
on Mon, 28 Jan 2008 16:22:33 +0900, Raj S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
writes:

|Look at the code.

Just because #{y} is expanded at compile time, so that class\_eval  
receives

puts " another hi"

whereas mere y cannot be referenced since its scope is different.

```
          matz.

```

---

<div class="post-metadata">

**Author:** ![dorelal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/3da27b/32.png) [@dorelal](https://www.ruby-forum.com/u/dorelal)\
**Post date:** [January 28, 2008, 5:22pm UTC](https://www.ruby-forum.com/t/whats-the-diff-between-puts-y-and-puts-y-in-class-eval/127320/3 "2008-01-28T17:22:15Z")

</div>

Hi Matz,

Thanks for the answer but I couldn’t quite follow it.

It seems that you are suggesting that the scope of “#{y}” is different  
from the scope of plain vanilla ‘y’ in “puts y”.

Could you please further elaborate on that. To me it seems like both of  
them have the same scope because they are both being used in the same  
method.

---

<div class="post-metadata">

**Author:** ![dorelal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/3da27b/32.png) [@dorelal](https://www.ruby-forum.com/u/dorelal)\
**Post date:** [January 28, 2008, 5:53pm UTC](https://www.ruby-forum.com/t/whats-the-diff-between-puts-y-and-puts-y-in-class-eval/127320/4 "2008-01-28T17:53:50Z")

</div>

> > > > > “R” == Raj S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

R\> Could you please further elaborate on that. To me it seems like both  
of  
R\> them have the same scope because they are both being used in the same  
R\> method.

Well, when you write this

y = " another hi"

class Wes  
end

Wes.class\_eval \<\<-END  
def hello  
puts “#{y}”  
puts y # I get wrong number of arguments error  
end  
END

1. ruby create the string at toplevel (where is defined `y’) and this  
give

```
def hello
   puts " another hi"
   puts y # I get wrong number of arguments error
end

```

1. the string is given to class\_eval, which create the method #hello  
in Wes

```
def hello
   puts " another hi"
   puts y # I get wrong number of arguments error
end

```

when the method is compiled, `y' is resolved as a call to a method (no local variable `y’ was defined in the def #hello)

When you call Wes.new.hello, ruby try to call this method and it give  
you  
an error.

Guy Decoux

---

<div class="post-metadata">

**Author:** ![dorelal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/3da27b/32.png) [@dorelal](https://www.ruby-forum.com/u/dorelal)\
**Post date:** [January 29, 2008, 3:21am UTC](https://www.ruby-forum.com/t/whats-the-diff-between-puts-y-and-puts-y-in-class-eval/127320/5 "2008-01-29T03:21:21Z")

</div>

On 1/28/08, Raj S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Could you please further elaborate on that. To me it seems like both of  
> them have the same scope because they are both being used in the same  
> method.

Compare to this:

class T  
def first  
“hello”  
end  
def second  
“chunky bacon”  
end  
end

y = “first”

T.class\_eval \<\<-END  
def hello  
puts #{y}  
end  
END

T.new.hello # prints “hello”

The key is that the “\<\<-END” is creating an interpolated string in the  
original context; the interpolation of #{y} isn’t happening during the  
call to “hello”, but rather as part of the string passed to  
class\_eval.

You are probably confused by the fact that in the sample code, the  
interpolation is happening inside of another string constant, which  
makes it look like it’s happening as part of “hello”. It’s not.

– ryan

---

<div class="post-metadata">

**Author:** ![dorelal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/3da27b/32.png) [@dorelal](https://www.ruby-forum.com/u/dorelal)\
**Post date:** [January 29, 2008, 4:48am UTC](https://www.ruby-forum.com/t/whats-the-diff-between-puts-y-and-puts-y-in-class-eval/127320/6 "2008-01-29T04:48:36Z")

</div>

Ryan Ingram wrote:

> On 1/28/08, Raj S. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > Could you please further elaborate on that. To me it seems like both of  
> > them have the same scope because they are both being used in the same  
> > method.
> 
> Compare to this:
> 
> class T  
> def first  
> “hello”  
> end  
> def second  
> “chunky bacon”  
> end  
> end
> 
> y = “first”
> 
> T.class\_eval \<\<-END  
> def hello  
> puts #{y}  
> end  
> END
> 
> T.new.hello # prints “hello”
> 
> The key is that the “\<\<-END” is creating an interpolated string in the  
> original context; the interpolation of #{y} isn’t happening during the  
> call to “hello”, but rather as part of the string passed to  
> class\_eval.
> 
> You are probably confused by the fact that in the sample code, the  
> interpolation is happening inside of another string constant, which  
> makes it look like it’s happening as part of “hello”. It’s not.
> 
> – ryan

Thanks for the explanation, I’ve been watching this thread and waiting  
for an explanation that I could comprehend. If I understand your  
explanation correctly, the steps are:

1. The substitution in the string:

str =\<\<STR  
def hello  
puts #{y}  
end  
STR

is performed. The scope is the global scope, so the string becomes:

str =\<\<STR  
def hello  
puts first  
end  
STR

1. The string is class\_eval’ed in the scope of class T, producing:

class T  
def first  
“hello”  
end

def second  
“chunky bacon”  
end

def hello  
puts first  
end  
end

1. When the method hello is called, the line:

puts first

outputs the return value of the first method.

Applying those steps to the op’s example:

> y = " another hi"
> 
> class Wes  
> end
> 
> Wes.class\_eval \<\<-END  
> def hello  
> puts “#{y}”  
> puts y # I get wrong number of arguments error  
> end  
> END

1. The string:

> \<\<-END  
> def hello  
> puts “#{y}”  
> puts y # I get wrong number of arguments error  
> end  
> END

becomes:

\<\<-END  
def hello  
puts “another hi”  
puts y # I get wrong number of arguments error  
end  
END

1. The class Wes is transformed into:

class Wes  
def hello  
puts “another hi”  
puts y  
end  
end

1. Then a statement such as:

w = Wes.new  
w.hello

produces an error because there is no variable or method named ‘y’  
inside class Wes:

rb:4:in `hello': undefined local variable or method `y’ for  
#Wes:0x25328 (NameError)

---

<div class="post-metadata">

**Author:** ![dorelal](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/3da27b/32.png) [@dorelal](https://www.ruby-forum.com/u/dorelal)\
**Post date:** [January 29, 2008, 11:18pm UTC](https://www.ruby-forum.com/t/whats-the-diff-between-puts-y-and-puts-y-in-class-eval/127320/7 "2008-01-29T23:18:09Z")

</div>

Yep, you’ve got it exactly.
