Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

eval and local variable

6 views
Skip to first unread message

Park Heesob

unread,
Jun 4, 2002, 10:27:38 PM6/4/02
to

Hi,

in following script

eval "foo = 'bar'"
p local_variables #--> ["foo"]
p eval "foo" #--> "bar"
p foo #--> foo.rb:4: undefined local variable or method `foo' for
#<Object:0x2ac38ce0> (NameError)

Why can't use foo variable directly?

Whereas in irb

# irb
irb(main):001:0> eval "foo = 'bar'"
"bar"
irb(main):002:0> p local_variables
["_", "foo"]
nil
irb(main):003:0> p foo
"bar"
nil

Park Heesob.

ts

unread,
Jun 5, 2002, 2:27:17 AM6/5/02
to
>>>>> "P" == Park Heesob <pha...@hananet.net> writes:

P> eval "foo = 'bar'"
P> p local_variables #--> ["foo"]
P> p eval "foo" #--> "bar"
P> p foo #--> foo.rb:4: undefined local variable or method `foo' for
P> #<Object:0x2ac38ce0> (NameError)

P> Why can't use foo variable directly?

When ruby compile the script, it find `foo' at this time there is no local
variable defined (eval is not yet executed) and ruby think that you have
wanted to write `foo()', i.e. a call to the method #foo

At runtime, eval will create a local variable, but when ruby execute the
lines `p foo' it will try to call the method #foo, because this is what it
has compiled. Here an example

pigeon% cat b.rb
#!/usr/bin/ruby
def foo
"ruby has called #foo"
end

eval "foo = 'bar'"
p local_variables

p eval "foo"
p foo
pigeon%

pigeon% b.rb
["foo"]
"bar"
"ruby has called #foo"
pigeon%

Guy Decoux

Park Heesob

unread,
Jun 5, 2002, 3:17:20 AM6/5/02
to

"ts" <dec...@moulon.inra.fr> wrote in message
news:200206050618...@moulon.inra.fr...

>
> When ruby compile the script, it find `foo' at this time there is no
local
> variable defined (eval is not yet executed) and ruby think that you have
> wanted to write `foo()', i.e. a call to the method #foo
>
> At runtime, eval will create a local variable, but when ruby execute the
> lines `p foo' it will try to call the method #foo, because this is what
it
> has compiled. Here an example
>

I think the problem is that Ruby cannot distinguish local variable from
method by its name.
If method called with prefix '&' or postfix '()' , there is no such
confusion.

Park Heesob.

ts

unread,
Jun 5, 2002, 3:34:53 AM6/5/02
to
>>>>> "P" == Park Heesob <pha...@hananet.net> writes:

P> I think the problem is that Ruby cannot distinguish local variable from
P> method by its name.

It can when you make for example an assignement

a = 12 # ==> local variable

when it's not an assignement, then ruby search if it exist a local
variable with this name. If the local variable is not found (i.e. it has
not seen a line where this variable was assigned) then it's a method call.

With Rite, you'll have a warning for this

/* method call without arguments */
#if 0
/* Rite will warn this */
rb_warn("ambiguous identifier; %s() or self.%s is better for method call",
rb_id2name(id), rb_id2name(id));
#endif

Guy Decoux


Kent Dahl

unread,
Jun 5, 2002, 3:37:51 AM6/5/02
to
Park Heesob wrote:
> If method called with prefix '&' or postfix '()' , there is no such
> confusion.

When and why is a method called with prefix '&'? I haven't seen this, so
now I'm confused.

--
(\[ Kent Dahl ]/)_ _~_ __[ http://www.stud.ntnu.no/~kentda/ ]___/~
))\_student_/(( \__d L b__/ NTNU - graduate engineering - 4. year )
( \__\_õ|õ_/__/ ) _)Industrial economics and technological management(
\____/_ö_\____/ (____engineering.discipline_=_Computer::Technology___)

Park Heesob

unread,
Jun 5, 2002, 3:43:47 AM6/5/02
to
Hi,

"Kent Dahl" <ken...@stud.ntnu.no> wrote in message
news:3CFDBFCF...@stud.ntnu.no...


> Park Heesob wrote:
> > If method called with prefix '&' or postfix '()' , there is no such
> > confusion.
>
> When and why is a method called with prefix '&'? I haven't seen this, so
> now I'm confused.

'&' is Perl's prefix, not Ruby's.
I metioned it just as an example.
Sorry for confusing :)

Park Heesob.


Olaf Klischat

unread,
Jun 6, 2002, 5:07:58 AM6/6/02
to
ts <dec...@moulon.inra.fr> writes:

> At runtime, eval will create a local variable, but when ruby execute the
> lines `p foo' it will try to call the method #foo, because this is what it
> has compiled.

Then at least the error message is confusing, isn't it?

> >>>>> "P" == Park Heesob <pha...@hananet.net> writes:
> P> p foo #--> foo.rb:4: undefined local variable or method `foo' for

Olaf
--
Olaf Klischat | TU Berlin computer science
Oberfeldstrasse 132 |
12683 Berlin, Germany |
phone: +49 30 54986231 | e-mail: klis...@cs.tu-berlin.de

ts

unread,
Jun 6, 2002, 5:28:52 AM6/6/02
to
>>>>> "O" == Olaf Klischat <klis...@cs.tu-berlin.de> writes:

O> Then at least the error message is confusing, isn't it?

>> >>>>> "P" == Park Heesob <pha...@hananet.net> writes:
P> p foo #--> foo.rb:4: undefined local variable or method `foo' for

Not for me, this mean that

* at compile type no local variable with the name 'foo' was defined
* at run time, no method with the name `foo' was defined


Guy Decoux

Christoph

unread,
Jun 6, 2002, 9:10:01 AM6/6/02
to
"ts" <dec...@moulon.inra.fr> wrote in message
...

> Not for me, this mean that

since you understand whats going on anyway;-)

>
> * at compile type no local variable with the name 'foo' was defined
> * at run time, no method with the name `foo' was defined

The difference of compile and runtime is blurred (in my mind at least;-)
and may explain the difficulties some people (including myself) have in
understanding visibility rules of local variables.

For example, I find it curious that Ruby raises a NameError when a
variable name is used before being declared, even so the interpreter
seems to have complete knowledge of all local_variable (that are
and will be) declared in the current scope.

---
p local_variables

begin
x = (eval "foo").nil? # doesn't raises a NameError since `foo' is
declared
# in the rescue clause
p foo # raises a NameError since `foo' is not
declared yet.
rescue => mes
p mes
foo = 'bar'
end

p x,foo
p local_variables

begin
x = eval "foo"
p foo
rescue => mes
p mes
foo = 'bar'
end

p x,foo

# ["x", "mes", "foo"]
# #<NameError: undefined local variable or method `foo' for
#<Object:0x100fb0a8>>
# true
# "bar"
---

and for good measure the eval version ...

---
eval %{
p local_variables

begin
x = (eval "foo").nil? # already raises a NameError ...
p foo
rescue => mes
p mes
foo = 'bar'
end

p x,foo # curiously this does not raise an `x' NameError

}

# results in
# []
# #<NameError: (eval):1: undefined local variable or method `foo' for
#<Object:0x100fb0a8>>
# nil
# "bar"
---

/Christoph


ts

unread,
Jun 6, 2002, 9:23:01 AM6/6/02
to
>>>>> "C" == Christoph <chr_...@gmx.net> writes:

C> and for good measure the eval version ...

You are using 1.7, no ?

:-)


Guy Decoux

Christoph

unread,
Jun 6, 2002, 9:39:52 AM6/6/02
to
"ts" <dec...@moulon.inra.fr> wrote in

...
> You are using 1.7, no ?

Yes ...

/Christoph


ts

unread,
Jun 6, 2002, 9:59:57 AM6/6/02
to
>>>>> "C" == Christoph <chr_...@gmx.net> writes:

C> "ts" <dec...@moulon.inra.fr> wrote in
C> ....


>> You are using 1.7, no ?

C> Yes ...

Then try it with 1.6.7 (but protect NameError in the rescue clause) and
see the result for `x'


Guy Decoux

Christoph

unread,
Jun 6, 2002, 11:04:50 AM6/6/02
to

"ts" <dec...@moulon.inra.fr> wrote in message
news:200206061352...@moulon.inra.fr...

Interesting (I just complied a 1.6 cvs branch), the result for the eval and
non-eval versions are actually the same (like a non-eval 1.7 version). Do
you consider the 1.7 behavior as a bug?

/Christoph

ts

unread,
Jun 6, 2002, 12:13:38 PM6/6/02
to
>>>>> "C" == Christoph <chr_...@gmx.net> writes:

C> Interesting (I just complied a 1.6 cvs branch), the result for the eval and
C> non-eval versions are actually the same (like a non-eval 1.7 version). Do
C> you consider the 1.7 behavior as a bug?

Well, I must say that it can seems strange to have as result `true' or
`nil' when you execute the same code normally or in #eval


Guy Decoux


Marcin 'Qrczak' Kowalczyk

unread,
Jun 10, 2002, 3:40:13 PM6/10/02
to
Fri, 7 Jun 2002 01:08:59 +0900, ts <dec...@moulon.inra.fr> pisze:

> Well, I must say that it can seems strange to have as result `true'
> or `nil' when you execute the same code normally or in #eval

For me eval is evil and static name resolving is preferable,
so I would rather aim at making eval unnecessary.

--
__("< Marcin Kowalczyk * qrc...@knm.org.pl http://qrczak.ids.net.pl/
\__/
^^
QRCZAK

0 new messages