Reputation: 123
perldoc
says "a list assignment in scalar context returns the number of elements on the right-hand side of the list assignment" but when I try this code:
perl -e '$_="aaaaa";print $v=(()=split //)'
The output is 1
which makes me confused. (The answer I expect is 5
.)
Can anybody explain this?
Upvotes: 10
Views: 679
Reputation: 14711
split
has some kind of crazy ultra-magic in it that allows it to know when it is on the right hand side of an assignment that has a list on the left hand side, and adjusts its behavior according to the number of items in that list.
This is described in perlfunc
as being done "to avoid unnecessary work", but you've found an observable difference in behavior caused by that optimization.
To see some evidence of what happened, run your script through Deparse like this:
perl -MO=Deparse -e '$_="aaaaa";print $v=(()=split //)'
Update: I went looking for the code that implements this, and it's not where I expected it to be. Actually the optimization is performed by the assignment operator (op.c:Perl_newASSIGNOP
) . split doesn't know that much about its context.
Upvotes: 8
Reputation: 11992
Yes, but :
perl -e '$_="aaaaa";print $v=(split //)'
gives 5, as well as
perl -e '$_="aaaaa";print $v=(@x=split //)'
Maybe your left-value () is dropping additional array elements ?
edit : by the way :
perl -e '$_="aaaaa";print $v=(($x,$y)=split //)'
returns 3, because the right sight of the $v=... command gives :
( $x , $y , ( a , a , a ) )
So in your original case, ()=split //
returns ( ( a , a , a , a , a ) ) (which has only one element)
Edit : bad array notation, and result was wrong because of a last minute changed of my test-case
Upvotes: -2
Reputation: 22421
According to split
documentation:
When assigning to a list, if LIMIT is omitted, or zero, Perl supplies a LIMIT one larger than the number of variables in the list <...>
Since you specify empty list, split
only returns 1 result and this number of results is exactly what ends in your variable.
Upvotes: 14
Reputation: 9354
Why are you assigning to an empty array? the ()=(split //)
bit. That's going to end up with - um, well, a mess. Or, in your case, an array with a size of one with not much in it.
Also, that's excessively obscure. perl has a sad reputation for being write-only, and all that modifying $_ and using it doesn't help others - or you - understand what is going on.
Try something like
perl -e '$v = (split //, "aaaaa"); print "$v\n"'
or, if you wish to replicate the behavior of your test:
perl -e '$v = () = (split //, "aaaaa"); print "$v\n"'
Upvotes: -1