http://www.perlmonks.org?node_id=866849


in reply to Re^5: Confused as to why the "casting context" is mis-behaving
in thread Confused as to why the "casting context" is mis-behaving

The "scalar context" guarantee that the perltrap item is talking about is only for the last expression of the list literal. Yes, not clear as worded.

I don't look at Perl internals much. I care a lot more about observable behavior. I mostly just have a lot of experience (mostly at PerlMonks) of watching people hit edge cases.

Here's a recent edge case:

print "Scalar assignment:\n"; $x = ( context(1), context(2), context(3) ); print "\$x = $x\n\n"; print "List assignment:\n"; @x = ( context(1), context(2), context(3) ); print "\@x = @x\n\n"; sub list { ( context(1), context(2), context(3) ) } print "Scalar assignment in sub:\n"; $x = list(); print "\$x = $x\n\n"; print "List assignment in sub:\n"; @x = list(); print "\@x = @x\n\n"; sub context { my $arg = shift; if(wantarray) { print "$arg: list context\n"; return("oranges", "lemons"); } elsif(defined(wantarray)) { print "$arg: scalar context\n"; return("apples"); } else { print "$arg: void context\n"; return("into the..."); } } __END__ Scalar assignment: 1: void context 2: void context 3: scalar context $x = apples List assignment: 1: list context 2: list context 3: list context @x = oranges lemons oranges lemons oranges lemons Scalar assignment in sub: 1: scalar context # shouldn't this be void context? 2: scalar context # shouldn't this be void context? 3: scalar context $x = apples List assignment in sub: 1: list context 2: list context 3: list context @x = oranges lemons oranges lemons oranges lemons

I briefly believed the reason for the scalar (not void) context for the commented lines so that you don't get warnings from:

use warnings; sub list { ('a','b','c') } my @all= list(); my $last= list(); # Doesn't produce a warning

- tye        

Replies are listed 'Best First'.
Re^7: Confused as to why the "casting context" is mis-behaving (void,void,scalar)
by chromatic (Archbishop) on Oct 22, 2010 at 18:38 UTC
    I believe the reason for the scalar (not void) context for the commented lines so that you don't get warnings from:

    I've always thought it was that the compiler can't perform static analysis across function calls. (By the time of assigning return values, does the compiler know that any element of the stack was a literal?)

      I've always thought it was that the compiler can't perform static analysis across function calls.

      That would be a reason for the warning to not happen (and a reasonable one). It is not a reason for the context to be scalar rather than void.

      But, yes, I tried to remember what was discussed when this inconsistency was brought up and threw in a half-remembered guess at the last minute. It turns out to be incorrect. The "useless use of constant in void context" doesn't happen for the return value of a sub, even when the sub is called in a void context.

      I don't recall specific enough details about the last time this came up to have found a prior discussion of it. But I eventually stumbled upon ysth providing a much better explanation of this exception, Re: If you believe in Lists in Scalar Context, Clap your Hands (which I don't believe is even the discussion I was remembering).

      - tye        

Re^7: Confused as to why the "casting context" is mis-behaving (void,void,scalar)
by ikegami (Patriarch) on Oct 22, 2010 at 22:57 UTC
    Scalar assignment in sub: 1: scalar context # shouldn't this be void context? 2: scalar context # shouldn't this be void context? 3: scalar context $x = apples

    It should be void, but it can't due to the way context is determined where it can vary at run-time. Known bug, but it can't readily be fixed.