On 7/18/06, Logan Capaldo <logancapaldo / gmail.com> wrote:
>
> On Jul 17, 2006, at 7:12 PM, Sean O'Halpin wrote:
>
> > On 7/18/06, Justin Collins <collinsj / seattleu.edu> wrote:
> >>
> >>
> >> Sean O'Halpin wrote:
> >> > On 7/17/06, Thorben Mueller <dingsi / mistburg.de> wrote:
> >> >> Rick Ashton schrieb:
> >> >> > Thanks guys
> >> >> >
> >> >> > But it still doesn't load the file into the current scope as I
> >> >> mentioned
> >> >> > before. Is there some way to do this?
> >> >> >
> >> >> > ie:
> >> >> >
> >> >> > $ echo a=5 > blah.rb
> >> >> > $ irb -r blah.rb
> >> >> > irb(main):001:0> a
> >> >> > NameError: undefined local variable or method `a' for
> >> main:Object
> >> >> >         from (irb):1
> >> >> >
> >> >> >
> >> >> > Thanks!
> >> >> >
> >> >>
> >> >> Hi Rick,
> >> >>
> >> >> try eval(File.read('blah.rb'))
> >> >>
> >> >> ~dingsi
> >> >>
> >> >>
> >> >
> >> > eval() won't create local variables - it will update one if it
> >> already
> >> > exists however:
> >> >
> >> > $ cat eval-test.rb
> >> > a = 42
> >> > $ cat eval-scope.rb
> >> > eval(File.read("eval-test.rb"))
> >> > p a
> >> > $ ruby eval-scope.rb
> >> > eval-scope.rb:2: undefined local variable or method `a' for
> >> > main:Object (NameError)
> >> >
> >> > $ cat eval-scope2.rb
> >> > a = nil
> >> > eval(File.read("eval-test.rb"))
> >> > p a
> >> > $ ruby eval-scope2.rb
> >> > 42
> >> >
> >> >
> >> > Regards,
> >> > Sean
> >> >
> >>
> >> Interestingly, it _does_ work for me within irb:
> >>
> >> $ cat test.rb
> >> puts "hi"
> >> a = 1
> >> $ irb
> >> irb(main):001:0> eval(File.read('test.rb'))
> >> hi
> >> => 1
> >> irb(main):002:0> puts a
> >> 1
> >> => nil
> >>
> >>
> >>
> >> Which I think will work for what the OP wanted?
> >>
> >> -Justin
> >>
> >>
> > You're right - another one of those little quirks of irb ;)
> >
> > (I'm too abashed to admit I missed the point)
> >
> > Regards,
> > Sean
> >
>
> It's not _really_ a little quirk of irb, it's the same quirk you
> noted of eval (Since irb uses #eval to well, evaluate ;) ).
>
> e.g.:
>
> % cat demo_eval.rb
> puts eval("x = 1")
> puts begin
> x
> rescue
> "At parse time, x has not been declared as a local variable (by
> assigning to it.)\n" +
>    "This means it will raise an exception when it gets evaluated here."
> end
>
> puts eval("x") # But x does indeed exist.
>
>
> % ruby demo_eval.rb
> 1
> At parse time, x has not been declared as a local variable (by
> assigning to it.)
> This means it will raise an exception when it gets evaluated here.
> 1
>
It's even quirkier than that even :)

# (ruby-talk 202571)
puts eval("x = 1")
puts begin
x
rescue
"At parse time, x has not been declared as a local variable (by
assigning to it.)\n" +
  "This means it will raise an exception when it gets evaluated here."
end

puts "But x does indeed exist."
puts eval("x")
begin
  puts x
rescue
  puts "or does it?"
end
p local_variables
__END__
1
At parse time, x has not been declared as a local variable (by
assigning to it.)
This means it will raise an exception when it gets evaluated here.
1
or does it?
["x"]

My point was that eval won't introduce local variables into the
current scope (which irb does because of the tricks it plays with
bindings). It appears that when eval is called without a binding, it
temporarily pushes the current frame, re-uses the binding in effect
when the eval was called, then pops the current frame back again which
I guess has the effect of erasing changes to local variables (but
someone should tell the local_variables method!). This creates the
effect of a kind of binding that persists between calls to eval but
which is inaccessible to the local scope (except via eval). At least,
that's how it seems to me. I'd be grateful for a definitive
explanation of what's going on in eval.c:6500ff.

Regards,
Sean