in reply to Re: An anomaly with List::Util::reduce and/or eval?
in thread An anomaly with List::Util::reduce and/or eval?

I was using a string because the '+' in the example was actually a runtime supplied argument (see Re: array problems).

I see the same errors, but I don't understand why eval would return undef.... Or maybe I do.

I think you hit the nail on the head liz!

<DEEP SPECULATION>Maybe eval is using wantarray to detect a void context and returning undef? But that would mean wantarray is failing to detect the body of reduce as a LIST context?


Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller
If I understand your problem, I can solve it! Of course, the same can be said for you.

  • Comment on Re: Re: An anomaly with List::Util::reduce and/or eval?

Replies are listed 'Best First'.
Re: Re: Re: An anomaly with List::Util::reduce and/or eval?
by blokhead (Monsignor) on Aug 12, 2003 at 19:50 UTC
    reduce { print wantarray ? "array\n" : defined wantarray ? "scalar\n" : "void\n" } 1 .. 2; # prints "void"
    So the eval must optimize itself based on the context, but a normal non-eval'ed block ending with $a + $b would not optimize away, and (I think) still perform and return the addition, even though being in void context.

    Certainly I agree that you are right, that this must be a bug in List::Util. The block should be in scalar context since the return value is the important part of this operation. I really wonder how the module can get the return value of something that it executes in void context??

    Also, I got some strange behavoir when I add a return statement to the eval. Both should behave the same way, but don't. Why on earth $a gets set to 4 for every addition is a mystery...

    my $result = reduce { print "eval: $a + $b\n"; eval "$a + $b" } 1 .. 4; print "result=$result\n\n"; # eval: 1 + 2 # eval: + 3 # eval: + 4 # result=4 $result = reduce { print "eval: return $a + $b\n"; eval "return $a + $b" } 1 .. 4; print "result=$result\n\n"; # eval: return 1 + 2 # eval: return 4 + 3 # eval: return 4 + 4 # result=4
    Update: sgifford claims to see scalar context from the block in his reply above -- running his code, I still get void context reported.. This is with Perl 5.8, and List::Util 1.07_00. But even in scalar context, he still gets the weird behavoir? The wonders never cease!

    blokhead

      Your code prints "scalar" for me as well.

      I'm using Perl 5.6.1, List::Util 1.11.

      Very strange indeed.

Re: Re: Re: An anomaly with List::Util::reduce and/or eval?
by sgifford (Prior) on Aug 12, 2003 at 19:32 UTC
    I thought the same thing, but it doesn't seem so:
    #!/usr/bin/perl -w use List::Util qw[ reduce ]; print reduce{ print "a = '$a', b = '$b'\n"; eval "showcontext($a + $b) +";} 1,2,3; sub showcontext { print "Context: "; if (wantarray) { print "array\n"; } elsif (defined(wantarray)) { print "scalar\n"; } else { print "void\n"; } $_[0]; }
    produces:
    $ perl /tmp/t76
    a = '1', b = '2'
    Context: scalar
    Use of uninitialized value in concatenation (.) or string at /tmp/t76 line 5.
    a = '', b = '3'
    Use of uninitialized value in concatenation (.) or string at /tmp/t76 line 5.
    Context: scalar
    3
    
Re: Re: Re: An anomaly with List::Util::reduce and/or eval?
by liz (Monsignor) on Aug 12, 2003 at 19:33 UTC
    ...failing to detect the body of reduce as a LIST context?

    But it is in scalar context: try forcing a list contect by prefixing the eval with () = ;-)

    Liz