Anyone understands eval?

Discussion in 'Perl Misc' started by shanx, Mar 18, 2005.

  1. shanx

    shanx Guest

    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
     
    shanx, Mar 18, 2005
    #1
    1. Advertising

  2. shanx

    Big and Blue Guest

    shanx wrote:
    >
    > $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.


    --
    Just because I've written it doesn't mean that
    either you or I have to believe it.
     
    Big and Blue, Mar 18, 2005
    #2
    1. Advertising

  3. shanx

    Jeff Guest

    shanx wrote:
    > 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
     
    Jeff, Mar 18, 2005
    #3
  4. shanx wrote:

    > 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--

    --
    Cocoa programming in Perl: http://camelbones.sourceforge.net
    Hire me! My resume: http://www.dot-app.org
     
    Sherm Pendley, Mar 18, 2005
    #4
  5. shanx

    shanx Guest

    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
     
    shanx, Mar 18, 2005
    #5
  6. shanx wrote:

    > 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?"
     
    Chris Mattern, Mar 18, 2005
    #6
  7. shanx

    Guest

    "shanx" <> wrote:
    > 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.

    > eval $a;


    You are not checking for errors on the eval.

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

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Mar 18, 2005
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Eric Newton
    Replies:
    3
    Views:
    9,422
    Brock Allen
    Apr 4, 2005
  2. Andy Dingley
    Replies:
    1
    Views:
    372
    Andrzej Adam Filip
    Mar 3, 2004
  3. chetan
    Replies:
    5
    Views:
    376
    John Harrison
    Sep 21, 2004
  4. Replies:
    20
    Views:
    923
    Netocrat
    Oct 24, 2005
  5. Daz
    Replies:
    12
    Views:
    164
    Dr J R Stockton
    Jul 18, 2007
Loading...

Share This Page