Anyone understands eval?

S

shanx

eval seems to be way too complicated for simple minded souls. I really
can't figure out what eval does behind the scenes even for some simple
things.

Here are a few samples:

1.

$a = "my $b = 10; print 'hi $b';";
eval $a;

Nothing happens. But if you change $a to

$a = 'my $b = 10; print "hi $b";'

... it works! You see the hi message now. Why is the quoting altering
eval's behavior? It's almost as if double quotes makes eval think that
the expression has already been evaluated.


2.

Excerpt from perldoc -f eval

"eval EXPR

EXPR is parsed and executed as if it were a little Perl program. It
is executed in the context of the current Perl program, so that any
variable settings or subroutine and format definitions remain
afterwards.
The value returned is the value of the last expression evaluated, or a
return statement may be used, just as with subroutines. The last
expression is evaluated in scalar or array context, depending on the
context of the eval."

Variable settings or subroutine definitions are supposed to remain
afterwards, but they remain only *sometimes*. Here is an example:

@tests = (
{
'cmd' => '$greeting = "hello";'
},
{
'cmd' => 'print "$greeting\n";'
}
);

foreach $i (@tests) {
eval $i->{cmd};
}

You would imagine that $greeting remains set for the second invocation,
but it doesn't.

-Shanker
 
B

Big and Blue

shanx said:
$a = "my $b = 10; print 'hi $b';";

So - assuming you hadn't set $b (and you should never use $a or $b as
variable - read perldoc on teh sort function to see why) the R/h side has
the value of $b interpolated as empty, to leave $a set to:

my = 10; print 'hi ';

This is illegal Perl, so when you eval it an error is generated. Errors
during eval get put into the $@ variable. Had you printed $@ after that
eval you would have seen the error message.
....
You would imagine that $greeting remains set for the second invocation,
but it doesn't.

It does for me. If I run your code (perl5.6.1 or perl5.8.5) I get
"hello" printed out.
 
J

Jeff

shanx said:
eval seems to be way too complicated for simple minded souls. I really
can't figure out what eval does behind the scenes even for some simple
things.

Here are a few samples:

1.

$a = "my $b = 10; print 'hi $b';";
eval $a;

Nothing happens. But if you change $a to

$a = 'my $b = 10; print "hi $b";'

.. it works! You see the hi message now. Why is the quoting altering
eval's behavior? It's almost as if double quotes makes eval think that
the expression has already been evaluated.

Because the double quotes force interpolation.

stampes@flux[82] ~ > perl -Mstrict -Mwarnings -de 1

Loading DB routines from perl5db.pl version 1.27
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(-e:1): 1
DB<1> $a = "my $b = 10; print 'hi $b';"

DB<2> x $a
0 'my = 10; print \'hi \';'

So when you eval $a, you don't get what you expect.

Variable settings or subroutine definitions are supposed to remain
afterwards, but they remain only *sometimes*. Here is an example:

@tests = (
{
'cmd' => '$greeting = "hello";'
},
{
'cmd' => 'print "$greeting\n";'
}
);

foreach $i (@tests) {
eval $i->{cmd};
}

You would imagine that $greeting remains set for the second invocation,
but it doesn't.

I'm not sure what you mean. When I run this code, it outputs "hello",
as I would expect.

~Jeff
 
S

Sherm Pendley

shanx said:
1.

$a = "my $b = 10; print 'hi $b';";
eval $a;

Nothing happens. But if you change $a to

$a = 'my $b = 10; print "hi $b";'

.. it works! You see the hi message now. Why is the quoting altering
eval's behavior?

It's not. It's changing what gets stored in $a. Try it with print() instead
of eval(), and it's obvious immediately what's going wrong:

Sherm-Pendleys-Computer:~ sherm$ cat testeval.pl
#!/usr/bin/perl

$a = "my $b = 10; print 'hi $b';";
print "$a\n";
Sherm-Pendleys-Computer:~ sherm$ perl testeval.pl
my = 10; print 'hi ';

Naturally, that "my = 10" isn't valid Perl, so it chokes when you eval it.
If you had checked for errors, Perl would have told you about it:

Sherm-Pendleys-Computer:~ sherm$ cat testeval.pl
#!/usr/bin/perl

$a = "my $b = 10; print 'hi $b';";
eval $a;
$@ && print "Eval error: $@";
Sherm-Pendleys-Computer:~ sherm$ perl testeval.pl
Eval error: syntax error at (eval 1) line 1, near "my ="
@tests = (
{
'cmd' => '$greeting = "hello";'
},
{
'cmd' => 'print "$greeting\n";'
}
);

foreach $i (@tests) {
eval $i->{cmd};
}

You would imagine that $greeting remains set for the second invocation,
but it doesn't.

It does for me:

Sherm-Pendleys-Computer:~ sherm$ cat testeval.pl
#!/usr/bin/perl

@tests = (
{ 'cmd' => '$greeting = "hello";' },
{ 'cmd' => 'print "$greeting\n";' }
);

foreach $i (@tests) {
eval $i->{cmd};
}
Sherm-Pendleys-Computer:~ sherm$ perl testeval.pl
hello

sherm--
 
S

shanx

Thanks! You're right. The second one didn't work for me because I had
a really old version of perl (5.004 ) in my path. It works after I
switched to 5.6.

-Shanker
 
C

Chris Mattern

shanx said:
eval seems to be way too complicated for simple minded souls. I really
can't figure out what eval does behind the scenes even for some simple
things.

Here are a few samples:

1.

$a = "my $b = 10; print 'hi $b';";
eval $a;

Nothing happens.

That's because double quotes interpolate. $b gets replaced with whatever
value is in $b before the string is assigned to $a. If $b is not defined,
this will produce illegal Perl code (specifically, $a now contains
"my = 10; print 'hi ';"), and Perl dutifully informs you that
your eval bombed in $@.
But if you change $a to

$a = 'my $b = 10; print "hi $b";'

.. it works!

That's because single quotes don't interpolate. $b remains $b and your
now legal Perl code evals without error.
You see the hi message now. Why is the quoting altering
eval's behavior?

Because the different quotes put different strings in $a.
It's almost as if double quotes makes eval think that
the expression has already been evaluated.


2.

Excerpt from perldoc -f eval

"eval EXPR

EXPR is parsed and executed as if it were a little Perl program. It
is executed in the context of the current Perl program, so that any
variable settings or subroutine and format definitions remain
afterwards.
The value returned is the value of the last expression evaluated, or a
return statement may be used, just as with subroutines. The last
expression is evaluated in scalar or array context, depending on the
context of the eval."

Variable settings or subroutine definitions are supposed to remain
afterwards, but they remain only *sometimes*. Here is an example:

@tests = (
{
'cmd' => '$greeting = "hello";'
},
{
'cmd' => 'print "$greeting\n";'
}
);

foreach $i (@tests) {
eval $i->{cmd};
}

You would imagine that $greeting remains set for the second invocation,
but it doesn't.
Did when I ran it. Copied your code into testit.pl:

syscjm@sakura:~$ perl testit.pl
hello
syscjm@sakura:~$

--
Christopher Mattern

"Which one you figure tracked us?"
"The ugly one, sir."
"...Could you be more specific?"
 
X

xhoster

shanx said:
eval seems to be way too complicated for simple minded souls.

Then, if you are a simple minded soul, don't use it.
I really
can't figure out what eval does behind the scenes even for some simple
things.

Here are a few samples:

1.

$a = "my $b = 10; print 'hi $b';";

You are not using strict.
You are not using warnings.
You are not checking to see what was actually stored in $a.

You are not checking for errors on the eval.

You obviously haven't tried very hard to figure it out.

Xho
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,898
Latest member
BlairH7607

Latest Threads

Top