George said:
I have
($pI,$vI)=($input=~/(\d+),(\d+)/) || ($input=~/(.*),(.*)/);
print "($pI,$vI)";
which work fine if $input="24,qwerr" but returns (1,) if $input="38,29"
why is that
why this "or" is not working, and how can I use ?: in this case
Do you have strict and warnings on? It doesn't look like it. You
should.
Precedence, context, and a peculiar behavior of "||" work together to
bring about this result. First off, "||" has higher precedence than
"=", so the expression is evaluated as
($pI,$vI)= ( ($input=~/(\d+),(\d+)/) || ($input=~/(.*),(.*)/) );
Now, in perldoc perlop we find
Binary "||" performs a short-circuit logical OR operation.
That is, if the left operand is true, the right operand is
not even evaluated. Scalar or list context propagates
down to the right operand if it is evaluated.
The peculiarity is in the last sentence.
The left operand is evaluated in boolean context, so the first regex
will return true or false, but not the list of captures. If the first
regex matches, that's it, so $pI is set to 1 and $vI remains undefined.
If it doesn't match, the second regex is evaluated in list context and
returns the two captures.
To make it work right, rewrite it as
($pI, $vI) = ( $input =~ /(\d+),(\d+)/) or
($pI, $vI) = ( $input =~ /(.*),(.*)/);
Note the use of the low-precedence "or" instead of "||".
Anno