in reply to Re^4: If you believe in Lists in Scalar Context, Clap your Hands
in thread If you believe in Lists in Scalar Context, Clap your Hands
Yes. I'd say that an array is a variable whose value is a list. Using the name or some other reference to an array yields that value or its length, depending on Context. In that sense, yes, I was implying that arrays do not make lists. A slice operation, on the other hand, takes a list value and makes a list which is a subset. (I'm open minded, though: if there is, in fact and invisible operator that makes lists out of arrays I would not be surprised.)No.
An array returns a list in list context, but it isn't a list. Just as localtime() isn't a list, although it will return a list in list context. In fact, every expression will return a list in list context, although that list may be empty or just contain a single value.
As for the slice operation, yes, it will take a subset of a list. On arrays though, it can return more.
@a = ()[3, 5, 6]; @b = @c[3, 5, 6]; say 0 + @a; say 0 + @b; __END__ 0 3
Following that model, in: $r = ($a, $b) = 0..11 ; the right-hand assignment: ($a, $b) = 0..11 happens first, so we get ($a=0, $b=1), then that is assigned to $r.... leaving to one side whether ($a, $b) is or isn't a list (given that for the right-hand assignment there's List Context, and in the left-hand one Scalar Context).... since the result is $r=12, right-associativity doesn't appear to be the whole story.You are quite wrong here. The list assignment operator in scalar context DOES NOT RETURN A LIST. It returns the number of elements on its right hand side. It sets $a and $b as side-effects - it doesn't return its left hand side. If you think of operators being shorthands for function calls, you may readWith thanks to all who pointed me in the right direction here, this is a piece of deeper magic. The right-associativity causes the 0..11 to be evaluated in List Context, and a list assignment is made to ($a, $b). So far, so straightforward. The interesting bit is that the next (left hand), scalar assignment, effectively reaches round the first (right hand) assignment and picks up the length of the list. This is well documented, but the significance of it didn't sink in when I read it however many years ago.
more or less as$r = ($a, $b) = 0 .. 11;
Now the above isn't exactly the same in the your line in detail, because I don't think you can mimic the assignment operator exactly in Perl code, but you get the idea.sassign(\$r, scalar lassign([\$a, \$b], range (0, 11))) sub lassign { my ($rhs, $lhs) = @_; for (my $i = 0; $i < @$rhs; $i ++) { $$rhs[$i] = $$lhs[$i]; } wantarray ? map {$$_} @$lhs : scalar @$rhs; } sub sassign: lvalue { my ($rhs, $lhs) = @_; $$rhs = $lhs; $$rhs; }
The point is, the assignment is a side-effect. The results are not returned. And also important, there's no magical reaching around by the first (leftmost) assignment. The first assignment operator doesn't look on its right hand side and say "my, my, lets see, I've a list here, I wonder how that list came to be. Oh, I see, in the past this list was created by an assignment. Let me reach even further back in the past, and see how many elements there were on its right hand side". No, by the time the leftmost assignment gets in the driver seat, it'll see two operands, a scalar lvalue, and a scalar value. How that scalar value got there doesn't interest the assignment operator. It could have been the return value of the add operation, or the return value of the lassign operator.
|
|---|