Help with eval

Am I missing something with eval? Why does this code not work?

eval("foo = 1")
puts foo

Gives:

C:\example\trunk>ruby script/runner lib/aggregate/keith.rb
C:/example/trunk/vendor/rails/railties/lib/commands/runner.rb:45:
undefined local variable or method `foo' for main:Obje
ct (NameError)
        from
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `eval'
        from
C:/noozler/trunk/vendor/rails/railties/lib/commands/runner.rb:45
        from
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in
`gem_original_require'
        from
c:/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in
`require'
        from script/runner:3

···

--
Posted via http://www.ruby-forum.com/.

Keith Carter wrote:

Am I missing something with eval? Why does this code not work?

Maybe it's a scoping issue with where you're running your code...works
fine for me in irb:

eval("foo = 1")

=> 1

foo

=> 1

···

--
Posted via http://www.ruby-forum.com/\.

Hm. You're right, that did work. How come the second bit below doesn't
work?

Loading development environment (Rails 2.0.2)

eval("foo = 1")

=> 1

foo

=> 1

begin

?> eval("bar=1")

bar
end

NameError: undefined local variable or method `bar' for
#<Object:0x27bf9ec>
        from (irb):5

···

--
Posted via http://www.ruby-forum.com/\.

Hm. You're right, that did work. How come the second bit below doesn't
work?

Loading development environment (Rails 2.0.2)>> eval("foo = 1")
=> 1
>> foo
=> 1
>> begin
?> eval("bar=1")
>> bar
>> end

NameError: undefined local variable or method `bar' for
#<Object:0x27bf9ec>
        from (irb):5

For even more fun, evaluate bar once you've gotten the NameError.

bar

=> 1

Sorry, but I don't know why, only that it seems odd.

···

On Jan 23, 4:13 pm, Keith Carter <kmarplecar...@yahoo.com> wrote:

yermej wrote:

Sorry, but I don't know why, only that it seems odd.

Wow. That is weird. I think evals are scoped as blocks. I'm going to
play with this for a bit.

···

--
Posted via http://www.ruby-forum.com/\.

variables created in eval can only been seen from eval. when you are irb you are already inside eval. there are some exceptions - search the archives.

if you post what you are trying to accomplish perhaps someone can help - no pattern that relies on eval creating vars in the local scope is going to pan out too well without a little dsl or some hackery - eval just won't suffice.

regards.

a @ http://codeforpeople.com/

···

On Jan 23, 2008, at 4:06 PM, Keith Carter wrote:

Wow. That is weird. I think evals are scoped as blocks. I'm going to
play with this for a bit.

--
share your knowledge. it's a way to achieve immortality.
h.h. the 14th dalai lama

ara.t.howard wrote:

if you post what you are trying to accomplish perhaps someone can
help - no pattern that relies on eval creating vars in the local
scope is going to pan out too well without a little dsl or some
hackery - eval just won't suffice.

I'm not trying to accomplish anything too fancy, and I was able to skirt
around the problem by declaring my variables outside of the eval block.

But now, my interest is piqued. What is dsl? What if I wanted to declare
a variable with a dynamic name using an eval block? (And I wanted to use
it outside of the eval block)

···

--
Posted via http://www.ruby-forum.com/\.

begin
  eval("bar=1")
  puts bar
end

Gives me and error too. but if I do

bar = 0
begin
  eval("bar=1")
  puts bar
end

It works! I am a ruby rookie so I dont know why this is so.

···

On Jan 24, 5:50 am, "ara.t.howard" <ara.t.how...@gmail.com> wrote:

On Jan 23, 2008, at 4:06 PM, Keith Carter wrote:

> Wow. That is weird. I think evals are scoped as blocks. I'm going to
> play with this for a bit.

variables created in eval can only been seen from eval. when you are
irb you are already inside eval. there are some exceptions - search
the archives.

if you post what you are trying to accomplish perhaps someone can
help - no pattern that relies on eval creating vars in the local
scope is going to pan out too well without a little dsl or some
hackery - eval just won't suffice.

regards.

a @http://codeforpeople.com/
--
share your knowledge. it's a way to achieve immortality.
h.h. the 14th dalai lama

Chirantan wrote:

It works! I am a ruby rookie so I dont know why this is so.

In the first example, you are defining the variable inside of the block.

In the second example, you've defined the variable outside of the block.

evals are scoped as blocks, and so variables created in them are not
available outside of the block.

···

--
Posted via http://www.ruby-forum.com/\.

evals are scoped as blocks, and so variables created in them are not
available outside of the block.

No, not really. Try this

moulon% ruby -e 'eval "a = 12"; eval "p a"'
12
moulon%

if the variable `a' was scoped, the second eval won't see it.

This is at compile time that ruby make the difference between an access to
a variable and a method call.

When you write :

  eval "a = 12"
  a

at compile time, ruby has not yet seen a variable with the name `a' and
it think that on the second line you try to call the method `a'

Something like this

def a
    p 24
end

eval "a = 12"
a

When you write it

a = 0
eval "a = 12"
a

when ruby compile the third line, it know that it exist a variable with the
name `a' (it has seen it at the first line) and this time it try to access
the variable `a' rather than call the method #a

Guy Decoux