in reply to List assignment in scalar context

"split" has some DWIM hackery to ensure that it doesn't work too hard, so it splits to one more than the container on the left, in the absence of a third-parameter hint.

-- Randal L. Schwartz, Perl hacker
Be sure to read my standard disclaimer if this is a reply.

  • Comment on •Re: List assignment in scalar context

Replies are listed 'Best First'.
Re^2: List assignment in scalar context
by Grimnebulin (Initiate) on Jan 10, 2005 at 19:05 UTC
    Aha. Guess I should have RTFM. It contradicts my usually-accurate intuition about how list/scalar context works in Perl, so I hope I can be forgiven.

    My real-life code that inspired this question goes something like this:

    my $count = my ($arg1, $arg2, $arg3) = split /\s+/, $argstring; $count == 3 or die "3 arguments expected; you supplied $count\n";
    So if I want the real argument count, I have to split into a temporary array first, or else use a dummy trailing array in the assignment list. Gross.

    I can't say I care for this feature. Smells like premature optimization to me. And I notice it doesn't work across function calls. That could be a nasty surprise for someone someday.

      my $count = my ($arg1, $arg2, $arg3) = split /\s+/, $argstring, -1; # ^^^^

      - tye        

      So if I want the real argument count, I have to split into a temporary array first, or else use a dummy trailing array in the assignment list. Gross.

      Personally i think the issue here is that what you are trying to do is much less common than the opposite. Ie, more people would rather have split// be faster on spliting a few elements out scenarios than they would with have it be slower but more consistant with other list returning functions. After all, split may be quite the wrong way to do this. Arguably

      my $count=()=$argstring=~/\s+/g; my ($arg1, $arg2, $arg3) = split /\s+/, $argstring;

      is better anyway, as if the $argstring is long and you only are going to store three elements then its better not do the actual splitting (creating new svs, populating them etc) when you dont need to.

      ---
      demerphq

Re^2: List assignment in scalar context
by dragonchild (Archbishop) on Jan 10, 2005 at 18:50 UTC
    That doesn't explain why the following happens:
    my ($a,$b,$c); my $n1 = ($a,$b,$c) = split /,/, "1,2,3,4,5"; my $n2 = my @x = ($a,$b,$c) = split /,/, "1,2,3,4,5"; print "$n1 ... $n2\n"; ---- 4 ... 3

    If it splits to one more, then why is that one going across one boundary, but not two?

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

      Oh come off it.

      sub list { return 1..5 } my ($a,$b,$c); my $n1 = ($a,$b,$c) = list(); my $n2 = my @x = ($a,$b,$c) = list(); print "$n1 ... $n2\n"; ---- 5 ... 3

      When you have scalar = list = list, you will always get the count of items in the rightmost list in scalar. In your $n2 example, your array is getting three items from the list. It isn't a scalar, so it isn't getting the count. What else would be expected? The behavior that merlyn is referring to is the reason why you don't see the complete count in the scalar.

        So, based on what you're saying, $n2 should equal 5. Since @x isn't a scalar, it shouldn't affect the count of $n2 because I have scalar = list = list = list ... so, why doesn't that work?

        Not to mention, where is it documented that When you have scalar = list = list, you will always get the count of items in the rightmost list in scalar. ?? I don't remember ever reading that ...

        Being right, does not endow the right to be rude; politeness costs nothing.
        Being unknowing, is not the same as being stupid.
        Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
        Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

      You tricked yourself.

      In the first case, the list assignment is evaluated in scalar context. In the second case, the list assignment is evaluated in list context and assigned to @x, yielding an array with three elements, which is then evaluated in scalar context. And an array with three elements evaluates to 3 in scalar context.

      Makeshifts last the longest.