Re^2: ||= oddity
by throop (Chaplain) on May 28, 2008 at 22:45 UTC
|
OK, once I knew what the answer was... it helped me find the answer in a manual. From 'Programming Perl, 2nd Edition', pp 92-93. It lists the assignment operators, including = and ||=, and says
List assignment may be done only with the plain assignment operator, =
+. In a list context, list assignment returns the list of new values
+just as scalar assignment does. ...
Hitting your thumb with a hammer - there's more than one way to do it! | [reply] [d/l] |
Re^2: ||= oddity
by moritz (Cardinal) on May 29, 2008 at 12:43 UTC
|
You may call me stupid, but why can't the scalar result of ||= be assigned to an array?
This works:
$ perl -wle 'my @a = 2; print @a'
2
$ perl -wle 'my @a = scalar 2; print @a'
2
$ perl -wle 'my @a = 2+2; print @a'
4
So we can see that you can assign a scalar to an array, and it does what you mean - it creates an array with one item.
But why can't you do it with the result of @array ||(1, 2, 3)? | [reply] [d/l] [select] |
|
|
... because it's been designed and implemented to operate the way it does — that's all :)
I think the crucial difference is that the normal assignment
operator (=) does not force scalar context upon its LHS (so the
array remains an array, not the number of its elements), while ||=
does. It's not so much an issue of not being able to assign a scalar to an array, but rather the problem of the array no longer being (treated like) an array internally...
| [reply] [d/l] [select] |
|
|
If it did work, it would produce useless results.
Given that (LHS ||= RHS) means (LHS = LHS || RHS),
Then (@a ||= (1,2,3)) means (@a = @a || (1,2,3)) and thus (@a = $#a+1 || 3).
Why would you ever want that.
On the other hand, it would be useful to expand the definition of the ||= operator so that (@a ||= EXPR) means (@a = @a ? @a : EXPR).
Similarly, it could be useful to expand the definition of &&= such that (@a &&= EXPR) means (@a = @a ? EXPR : ()).
However, none of **=, +=, *=, &=, <<=, -=, /=, |=, >>=, .=, %=, ^=, //= and x= would be useful for arrays.
| [reply] [d/l] [select] |
|
|
perl -we '@bar = (); @bar = @bar || (1, 2, 3); warn "(@bar)";'
you see that the array is filled with the right values: (1, 2, 3); but that's still useless for indeed when the array isn't empty at the beginning,
perl -we '@bar = (42, 5); @bar = @bar || (1, 2, 3); warn "(@bar)";'
the or operator returns the length of the array so the array will contain only (2).
Nice trap.
| [reply] [d/l] [select] |
|
|
However, none of **=, +=, *=, &=, <<=, -=, /=, |=, >>=, .=, %=, ^=, //= and x= would be useful for arrays.
Actually, x= would be:
$ perl -we '@bar = (42, 5); (@bar) = (@bar) x 5; warn "(@bar)";'
(42 5 42 5 42 5 42 5 42 5) at -e line 1.
$ perl -we '@bar = (42, 5); (@bar) x= 5; warn "(@bar)";'
Can't modify array dereference in repeat (x) at -e line 1, near "5;"
Execution of -e aborted due to compilation errors.
$
| [reply] [d/l] |