A local variable created in eval is only visible in eval.
eval("name = 'Alice'")
puts eval("name")
Well, perhaps ruby can be changed to make it work like a P language
svg% cat a.pl
#!/usr/bin/perl -w
use strict;
{
my $m;
sub aa { eval '$m += 2' }
sub bb { eval 'print "bb : $m\n"' }
sub cc { $m += 3 }
sub dd { print "dd : $m\n" }
}
for (0 .. 3) {
aa(); bb();
cc(); dd();
}
svg%
svg% ./perl -v a.pl
This is perl, v5.8.3 built for i686-linux
Copyright 1987-2003, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using `man perl' or `perldoc perl'. If you have access to the
Internet, point your browser at http://www.perl.com/, the Perl Home Page.
You can change existing variables, but cannot add new
variables.
It’s nice to know that eval() works in this way. Maybe in the future I’ll
use it for change variable value but this time I have to change every 30
local variables to global variables.
If I need (and can) to write:
name = nil
sname = nil
age = nil
eval("name = 'Alice'")
eval("sname = 'Smith'")
eval("age = '19'")
better is to write just:
name = 'Alice'
sname = 'Smith'
age = '19'
but the problem is I don’t know the names of that variables for now, so I
need to make them parameters:
However this bombs: eval(“name = ‘Alice’”, binding); puts name
This is probably because the reference to name is compiled before
eval() is called. Basically: the local variable is created but
the compiled code does not bind to it.
Try it in a program instead of in irb. That fails.
enigodev % cat t.rb
#!/usr/bin/ruby
eval(‘name = “alice”’,binding)
puts name
enigodev % ./t.rb
./t.rb:4: undefined local variable or method `name’ for main:Object
(NameError)
enigodev %
If one replaces name with @name, then it works. There is probably a
logical explanation for why local variables behave in this way within an
eval, but I do find it surprising, coming from Perl.
Kirk Haines
···
On Wed, 21 Apr 2004, Kristof Bastiaensen wrote:
There is
You can use Kernel#binding to get the current binding,
and pass it to eval:
Oh… That’s strange! So eval creates a new binding for new local
variables, instead of the given binding. I wonder if that is the intended
behaviour… Maybe it could be a solution to declare the variables that
you need:
fname, sname, age = nil
<code using fname, sname, age>
The variables that you don’t need will be inside eval,
but you don’t need them anyway.
···
On Wed, 21 Apr 2004 14:13:32 +0200, Szymon Drejewicz wrote:
Kristof Bastiaensen wrote:
There is
no, unfortunately it works that way only in IRB not in Ruby script.
“Szymon Drejewicz” drejewic@wsisiz.edu.pl schrieb im Newsbeitrag
news:c65k9g$bc3$1@portraits.wsisiz.edu.pl…
name = nil
eval(“name = ‘Alice’”)
puts name
You can change existing variables, but cannot add new
variables.
It’s nice to know that eval() works in this way. Maybe in the future
I’ll
use it for change variable value but this time I have to change every 30
local variables to global variables.
If I need (and can) to write:
name = nil
sname = nil
age = nil
eval("name = 'Alice'")
eval("sname = 'Smith'")
eval("age = '19'")
better is to write just:
name = 'Alice'
sname = 'Smith'
age = '19'
but the problem is I don’t know the names of that variables for now, so
I
need to make them parameters:
So I think it is candidate for Ruby-Proposal to make a additional
binding named i.e. “MAIN_BINDING” wich points current script…
The main binding is available already, 2. your proposal won’t help
since evat still is cannot create variables in that binding that you can
access in code, 3. even if eval could do that how would you want to use
that? I mean, you have to know var names to use them directly so what do
you gain by eval. OTOH, if you have those names only in some kind of
collection (array, etc.) then you can as well use a hash to store them.
IMHO you are looking for the wrong solution.
Maybe you should rather use a Hash instead of variables.
OpenStruct is another option that comes to mind:
16:36:35 [ruby]: ruby os.rb
16:36:39 [ruby]: cat os.rb
require ‘ostruct’
str = OpenStruct.new
p str
str.name = ‘foo’
p str
str.bar = ‘hello’
p str
16:36:51 [ruby]:
In message “Re: binding - how to get current script?” on 04/04/21, Kirk Haines khaines@enigo.com writes:
If one replaces name with @name, then it works. There is probably a
logical explanation for why local variables behave in this way within an
eval, but I do find it surprising, coming from Perl.
Local variable determination is done in compile time, so that eval
(which is done in run time) cannot affect the determination. It’s
just too late. But “irb” does compile and execute line by line.
That’s the reason eval works for irb (i.e. eval is executed before
compiling the next line).
If one replaces name with @name, then it works. There is probably a
logical explanation for why local variables behave in this way within an
eval, but I do find it surprising, coming from Perl.
Local variable determination is done in compile time, so that eval
(which is done in run time) cannot affect the determination. It’s
just too late. But “irb” does compile and execute line by line.
That’s the reason eval works for irb (i.e. eval is executed before
compiling the next line).
matz.
Why is there this difference between compile time and runtime? I had
assumed compile time was just a big eval call? Also, what happens when
you eval inside an eval is that a seperate scope or the same?
Charles Comstock
···
In message “Re: binding - how to get current script?” > on 04/04/21, Kirk Haines khaines@enigo.com writes:
In message “Re: binding - how to get current script?” on 04/04/22, Charles Comstock cc1@cec.wustl.edu writes:
Why is there this difference between compile time and runtime? I had
assumed compile time was just a big eval call? Also, what happens when
you eval inside an eval is that a seperate scope or the same?
eval does compile given string, then run compiled internal AST. Same
compile-time/run-time principle is applied in eval too.