From: "David A. Black" Date: 2001-09-04T03:13:36+09:00 Subject: [ruby-talk:20798] Re: Indirect eval doesn't work?? Hello -- On Tue, 4 Sep 2001, Wai-Sun Chia wrote: > Dear Rubyists, > I have this Ruby code: > > ================== foo.rb ==================== > #!/usr/bin/ruby > > code = "" > File.open ("foo.tmpl" ,"r") { |fd| > fd.each { |line| > code << line > } > } > > class Foo > end > > puts Foo.public_instance_methods.inspect > print code > eval code > puts Foo.public_instance_methods.inspect > ============================================== > > And this data file: > > ================= foo.tmpl =================== > class Foo > bar = 9999 > def foo_#{bar} > puts "this is in foo" > end > end > ============================================== > > When I run it, I get: > [] > class Foo > bar = 9999 > def foo_#{bar} > puts "this is in foo" > end > end > > ["foo_"] > > > Why is it that #{bar} doesn't get extrapolated? Because the # introduces a comment :-) Here are two examples which illustrate (I hope) the role of scope here: class A a = 9999 def thing_#{a} guess what? that's a comment! end end p A.instance_methods # => ["thing_"] class B b = 9999 eval <<-EOE def thing_#{b} # now #{...} will get interpolated end EOE end p B.instance_methods # => ["thing_9999"] In the first example (A), you've got a bare #, not inside a string. So it's a comment. And... if you put the whole thing in a string, and then eval it, the # is still a comment: str = <<'EOS' class A a = 9999 def thing_#{a} end end p A.instance_methods EOS eval str # => ["thing_"] That's essentially what happened in your case. You read the string in from a file, but that isn't relevant here. See case B, above. Another variation on the theme is: a = 9999 str = <