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

Eval question

2 views
Skip to first unread message

Justin Johnson

unread,
Jul 24, 2002, 7:18:55 AM7/24/02
to
I've got a question about 'eval'. In the following example (which doesn't
work by the way) where does 'val' live?

class MyClass
def tryIt( str )
eval str
p val
end
end

a = MyClass.new
a.tryIt( "val = 10" )

I was initially thinking that 'val' would be treated as a local to 'tryIt'.
Maybe 'eval' works a little differently to how I thought it might?

--
Justin Johnson.

Tom Gilbert

unread,
Jul 24, 2002, 7:37:23 AM7/24/02
to

It's local to the scope of the string being eval'd. Try this:

class MyClass
def tryIt( str )

val = eval str
p val
end
end

a = MyClass.new
a.tryIt( "val = 10" )

Tom.
--
.^. .-------------------------------------------------------.
/V\ | Tom Gilbert, London, England | http://linuxbrit.co.uk |
/( )\ | Open Source/UNIX consultant | t...@linuxbrit.co.uk |
^^-^^ `-------------------------------------------------------'

Justin Johnson

unread,
Jul 24, 2002, 7:49:12 AM7/24/02
to
I see. Thanks.

Is there anyway other way to create locals without explicitly setting them?

--
Justin Johnson.

"Tom Gilbert" <t...@linuxbrit.co.uk> wrote in message
news:2002072411...@offended.co.uk...

Thomas Søndergaard

unread,
Jul 24, 2002, 8:40:19 AM7/24/02
to

> I see. Thanks.
>
> Is there anyway other way to create locals without explicitly
> setting them?

val = nil
eval "val = 10"
puts val # -> 10

So val is created in a scope local to the eval invocation, unless it already exists in the nesting scope. I think :-)

Thomas

ts

unread,
Jul 24, 2002, 9:07:20 AM7/24/02
to
>>>>> "T" == =?iso-8859-1?Q?Thomas S=F8ndergaard?= <iso-8859-1> writes:

T> So val is created in a scope local to the eval invocation, unless it
T> already exists in the nesting scope. I think :-)

No, not really :-)

For example

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

If the variable `a' is created in a scope local to the first #eval, then
this variable will no be accessible for the second #eval

T> puts val # -> 10

The problem is on this line. This is at *compile* time that ruby make the
difference between an access to a local variable or a method call,
i.e. ruby must make the choice between

(1) : puts val # I try to access the local variable `val'
(2) : puts val() # I call the method #val

this choice is made at compile time when ruby know *only* if it exist a
local variable and the rule is simple

* if a variable 'val' was previously found then it make the choice (1)
* otherwise it make the choice (2)

For example with

eval "val = 12"
p val

when it compile the second line, it has not yet executed the string for
#eval this mean that at this step it don't exist a local variable `val'
and ruby consider that it's a method call, i.e.

eval "val = 12"
p val()

At runtime
* #eval will create a local variable `val'
* *but* in the second line, ruby will try to call the method #val

Now when you write

val = nil
eval "val = 12"
p val

when it compile the first line, it has found a new variable 'val'
when it compile the third line, it know that it exist a variable with the
name `val' and in this case it will create the node to access a local
variable.

At runtime, the 3 lines work with the same variable


p.s.: You'll have a similar problem with attribute writer


Guy Decoux

Justin Johnson

unread,
Jul 24, 2002, 10:39:29 AM7/24/02
to

This is exactly the information I was looking for!

So even this works:

eval "val = 12"
val = val
p val

because at compile time the 'val' variable has been seen now.

I was just making sure that locals are only seen at compile-time, not
run-time and that there was no way of creating them at run-time (eval
compiles code).

--
Justin Johnson.

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

0 new messages