Alien has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks !
I was writing some code today and I stumbled across something I find curious :
sub testc1 { if(defined wantarray()) { print "scalar\n"; } elsif(wantarray()) { print "array\n"; } else { print "void context\n"; } } testc1(); $a=testc1(); @a=testc1();
and
sub testc2 { if(wantarray()) { print "array\n"; } elsif(defined wantarray()) { print "scalar\n"; } else { print "void context\n"; } } $x=testc2(); @x=testc2(); testc2();
My question is : how come testc2 prints the right calling contexts but testc1 doesn't ?

Replies are listed 'Best First'.
Re: How do I check the return value of wantarray?
by imp (Priest) on Apr 04, 2007 at 15:09 UTC
    Because in the first case it isn't possible to reach the branch that tests if wantarray is true, since it is an elsif after testing if it is defined.
    if(defined wantarray()) { } elsif(wantarray()) { }
Re: How do I check the return value of wantarray?
by mreece (Friar) on Apr 04, 2007 at 15:35 UTC
    as this demonstates, wantarray is defined in both scalar and list context (which is why your testc1 fails), but true only in list context.
    sub testc { if (defined wantarray() and not wantarray()) { print "scalar\n"; } elsif (defined wantarray() and wantarray()) { print "array\n"; } elsif (not defined wantarray()) { print "void\n"; } } my $x = testc(); my @x = testc(); testc();
Re: How do I check the return value of wantarray?
by kyle (Abbot) on Apr 04, 2007 at 15:14 UTC

    Well, one's written correctly and the other isn't. It seems as though you think that wantarray being defined is separate from whether it's true or false when actually your testc1 will say 'scalar' for the instance where it is both defined and true.

Re: How do I check the return value of wantarray?
by derby (Abbot) on Apr 04, 2007 at 15:32 UTC

    wantarray's kinda wonky - returning 1 if list context, "" if scalar and undefined if void -- you can normalize that to 1 for list, 0 for scalar and -1 for void. The only trick is to force the "" into an integer (IV) by doing an integer operation (+0).

    my $w = defined wantarray() ? wantarray()+0 : -1; my %v = ( -1 => 'void', 0 => 'scalar', 1 => 'array' ); print $v{$w}, " context\n";

    -derby