Ryan Ingram wrote:
On 1/28/08, Raj S. [email protected] 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:
- 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
- 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
- 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
- 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
- The class Wes is transformed into:
class Wes
def hello
puts “another hi”
puts y
end
end
- 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)