I'd like to perform some convoluted variation of the @a = @b || @c
assignment, with the intent of taking @b
if non-empty (hence true in a boolean sense), @c
otherwise. The documentation explicitely tells me I can't. (And it's right about the fact, too!)
The "||", "//" and "&&" operators return the last value evaluated (unlike C's "||" and "&&", which return 0 or 1).
[...]
In particular, this means that you shouldn't use this for selecting between two aggregates for assignment:
@a = @b || @c; # this is wrong @a = scalar(@b) || @c; # really meant this @a = @b ? @b : @c; # this works fine, though
Unfortunately, it doesn't really tell me why.
What I expected would happen was this:
@a =
is an array assignment, inducing list context on the right hand side.@b || @c
is the right hand side, to be evaluated in list context.||
is C-style short-circuit logical or. It evaluates left to right (if needed) and propagates context.@b
is evaluated in list context. If true (i.e., non-empty), it is returned.- if not,
@c
is evaluated in list context as well, and returned.
Obviously, my penultimate statement is wrong. Why? And, more importantly, which part of the documentation or sources account for this behavior?
PS: out of the question's scope, the reason I refrain from the documentation's suggestion of using the ternary operator is that my @b
is actually a temporary (a function call result).