Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Eval str return different from Eval block return

by demerphq (Chancellor)
on May 17, 2002 at 09:28 UTC ( #167243=perlquestion: print w/ replies, xml ) Need Help??
demerphq has asked for the wisdom of the Perl Monks concerning the following question:

Consider the following code
sub capture {\@_}; # the eval here returns 1 to make for a cheap check for success. # we could check $@ but why bother? sub readonly{ my $v=$_[0]; eval{$_[0]=$v;1} ? 0 : 1 } $\="\n"; print "No eval :",readonly(capture(5)->[0]); eval ' print "In str eval :",readonly(capture(5)->[0]); '; eval { print "In block eval :",readonly(capture(5)->[0]); }; print "Block Eval ret :",readonly(eval{capture(5)}->[0]); print "Str Eval ret :",readonly(eval'capture(5)'->[0]);
Now you would expect that these would all output the same thing. But they dont!

No eval :1 In str eval :1 In block eval :1 Block Eval ret :1 Str Eval ret :0
Can anybody explain this behaviour? Is it consistent across perl versions? (tested 5.6.1 AS631)

Why should the return from a string eval be any different from the return from a block eval? (podmaster suggests that this is documented somewhere.. But so far cant find it. Can anybody else?)

Do you agree that this is a bug in perl that should be reported?

Thanks for you help in advance,

Yves / DeMerphq
---
Writing a good benchmark isnt as easy as it might look.

Comment on Eval str return different from Eval block return
Select or Download Code
Re: Eval str return different from Eval block return
by demerphq (Chancellor) on May 17, 2002 at 09:39 UTC
    Addendum:

    podmaster points out that the last example will choke under strict. However on my machine replacing it with Zaxos suggestion

    print "Str Eval ret :",readonly((eval'capture(5)')->[0]);
    Makes strict happy, but the bug remains (at least on my system.)
    use strict; sub capture {\@_}; sub readonly{ my $v=$_[0]; eval{$_[0]=$v;1} ? 0 : 1 } $\="\n"; print "No eval :",readonly(capture(5)->[0]); eval ' print "In str eval :",readonly(capture(5)->[0]); '; eval { print "In block eval :",readonly(capture(5)->[0]); }; print "Block Eval ret :",readonly(eval{capture(5)}->[0]); print "Str Eval ret :",readonly((eval'capture(5)')->[0]); __END__ No eval :1 In str eval :1 In block eval :1 Block Eval ret :1 Str Eval ret :0

    Yves / DeMerphq
    ---
    Writing a good benchmark isnt as easy as it might look.

      Here is an extra test case - this one also returns correctly:
      print "Eval all:",eval'readonly(capture(5)->[0])';

      You have moved into a dark place.
      It is pitch black. You are likely to be eaten by a grue.
Re: Eval str return different from Eval block return
by Zaxo (Archbishop) on May 17, 2002 at 09:43 UTC

    You have a precedence/grouping problem:

    print "Eval ret:",readonly((eval'capture(5)')->[0]);
    and
    print "Eval ret:",readonly(eval('capture(5)')->[0]);
    both print "Str Eval ret   :1"

    Update: Now that is odd that the grouping doesn't work for you,, mine's on Linux/Perl5.6.1.

    Update 2 : Sure does look like a platform difference, and where one should not be. I can confirm that demerphq's initial results agree with what mine does with that code. It appears that it's only the parenthesized ones that differ.

    Update 3 : One more test case:

    print "Eval ret:",readonly(eval('capture(5)'->[0]));
    prints "Str Eval ret   :0" on mine. It looks like AS groups thataway. Curiouser and curiouser.

    After Compline,
    Zaxo

      Which OS and Perl version Zaxo? I still get incorrect results
      use strict; use warnings; sub capture {\@_}; sub readonly{ my $v=$_[0]; eval{$_[0]=$v;1} ? 0 : 1 } $\="\n"; print "No eval :",readonly(capture(5)->[0]); eval ' print "In str eval :",readonly(capture(5)->[0]); '; eval { print "In block eval :",readonly(capture(5)->[0]); }; print "Block Eval ret :",readonly(eval{capture(5)}->[0]); print "Str Eval ret :",readonly((eval'capture(5)')->[0]); print "Str Eval ret2 :",readonly(eval('capture(5)')->[0]); __END__ No eval :1 In str eval :1 In block eval :1 Block Eval ret :1 Str Eval ret :0 Str Eval ret2 :0

      Yves / DeMerphq
      ---
      Writing a good benchmark isnt as easy as it might look.

        On Win NT and AS perl 5.6.1 you get

        --<br> No eval :1 In str eval :1 In block eval :1 Block Eval ret :1 Str Eval ret :0 Str Eval ret2 :0 --
        Anthony Staines
      Not on Win2k / ActivePerl 5.6.1 they don't. So this could be a platform issue then?
      No eval :1 In str eval :1 In block eval :1 Block Eval ret :1 Str Eval ret :0 Str Eval ret2 :0
      Update:

      On the same machine, with cygwin and perl 5.6.1, it runs fine:

      No eval :1 In str eval :1 In block eval :1 Block Eval ret :1 Str Eval ret :1 Str Eval ret2 :1


      You have moved into a dark place.
      It is pitch black. You are likely to be eaten by a grue.
Re: Eval str return different from Eval block return
by broquaint (Abbot) on May 17, 2002 at 10:01 UTC
    Running Linux 2.4.2-2 with 5.6.0, 5.6.1 and 5.7.3 I get this ouput
    No eval :1 In str eval :1 In block eval :1 Block Eval ret :1 Str Eval ret :0
    But adding brackets in Str Eval ret I get the expected results
    # added parentheses like so # print "Str Eval ret :",readonly(eval('capture(5)')->[0]); No eval :1 In str eval :1 In block eval :1 Block Eval ret :1 Str Eval ret :1
    And finally using demerphq's updated code here I get
    No eval :1 In str eval :1 In block eval :1 Block Eval ret :1 Str Eval ret :1 Str Eval ret2 :1

    HTH

    _________
    broquaint

Re: Eval str return different from Eval block return
by alien_life_form (Pilgrim) on May 17, 2002 at 15:19 UTC
    Greetings,

    Winnt, AS 5.6.1 631.
    Using -w i get:

    Name "main::capture(5)" used only once: possible typo at strange.pl li +ne 15. Use of uninitialized value in eval "string" at strange.pl line 15. No eval :1 In str eval :1 In block eval :1 Block Eval ret :1 Str Eval ret :0
    WTF? regardless of the warning, the given example runs under strict 'refs'. If I use eval "readonly(5)->[0]" it stops complaining (but still the results are wrong.
    And the "Block eval ret" thing sets $@ to
    Modification of a read-only value attempted at strange.pl line 4.
    Uh?
    Cheers,
    alf
    You can't have everything: where would you put it?
      !?!!

      Can you tell me what happens when you use the code in Re: Re: Eval str return different from Eval block return?

      We are running the same version of Perl so im suprised we are having different results. (ok im W2k not NT propper, but still...)

      Thanks,

      Yves / DeMerphq
      ---
      Writing a good benchmark isnt as easy as it might look.

        Greetings,

        The warning disappears then.
        I still get

        Modification of a read-only value attempted at strange2.pl line 4.
        for $@ at "Block Eval ret" though.
        Cheers,
        alf
        You can't have everything: where would you put it?

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://167243]
Approved by broquaint
Front-paged by gmax
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (10)
As of 2014-09-23 20:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (241 votes), past polls