Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I assign @b || @c to @a in Perl?

Tags:

perl

grammar

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).

like image 548
JB. Avatar asked Aug 31 '09 14:08

JB.


1 Answers

The logical-or operator ( "||" ) evaluates its left hand argument in scalar context.

The reason it does this is to figure out if the argument is true. Boolean context, being a special case of scalar context, forces it into scalar context.


From perldoc perlop "C-style-Logical-Or"

Binary "||" performs a short-circuit logical OR operation. That is, if the left operand is true, the right operand is not even evaluated. ...


From perldoc perldata "Scalar values":

.... The Boolean context is just a special kind of scalar context where no conversion to a string or a number is ever performed.

like image 121
Brad Gilbert Avatar answered Sep 21 '22 12:09

Brad Gilbert