Bizarre precedence quirk (bug?)

J

J Krugman

I don't know whether this is a bug or what, but it's about the most
bizarre Perl "quirk" (to keep it printable) I've ever come across,
and I've seen my share. If I run the following Perl script:

$x = $y = 1;
$y ||= ($x &&= 0);
print "$x\n";

The output is
1

!!! What on earth is up with THAT??? Just to make sure I was not
losing my mind, I ran this script as well:

$x = $y = 1;
($x &&= 0);
print "$x\n";

and the output was empty (undef), as expected. Why should the &&=
assignment have a different effect depending on whether one prepends
"$y ||= " to it or not?

jill
 
J

jonnytheclown

It's what I would expect. In the second line...

$y ||= ($x &&= 0)

$y is already true - so the ($x &&= 0) does not get evaluated - so $x
does not change.

In the second example I would have expected it to print 0 rather than
empty (undef)
 
X

xhoster

J Krugman said:
I don't know whether this is a bug or what, but it's about the most
bizarre Perl "quirk" (to keep it printable) I've ever come across,
and I've seen my share. If I run the following Perl script:

$x = $y = 1;
$y ||= ($x &&= 0);
print "$x\n";

The output is
1

!!! What on earth is up with THAT???

If you used:

$y or $y=($x &&= 0);

What would you have expected to happen? Why would expect your version
to do something different than my version?

Just to make sure I was not
losing my mind, I ran this script as well:

$x = $y = 1;
($x &&= 0);
print "$x\n";

and the output was empty (undef), as expected.

Uh, I think you *are* losing your mind. I get zero, not empty or undef.

Xho
 
A

A. Sinan Unur

I don't know whether this is a bug or what,

About 20 years ago, when I was still didling around with my trusty ZX
Spectrum (and trust me, that machine had bugs), I decided that it was
always more effective to assume that unexpected output generated by the
computer was my fault. This assumption has not been violated (at least
for me) since then.
$x = $y = 1;
$y ||= ($x &&= 0);

The short-circuit behavior of logical operators is well documented. In
fact, you use it every time you open a file:

open(my $file, '<', 'filename') || die $!;

If || did not short-circuit, code like this would be impossible to
write.

So, in the expression above, $y is already true. The rest is not
evaluated.
print "$x\n";
The output is
1

!!! What on earth is up with THAT???

Please, spare the yelling. Go back and take a look at 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.

Of course, instead of printing 1, I would have preferred that your
computer slapped you for using such an expression in the first place.
Are you trying to trip up future readers of your code? What is wrong
with:

$x &&= 0;
$y ||= $x;

$x = $y = 1;
($x &&= 0);
print "$x\n";

and the output was empty (undef), as expected.

How can that be?

#! /usr/bin/perl

use strict;
use warnings;

my $x = my $y = 1;

$x &&= 0;

print "$x\n";

__END__

C:\Temp> p
0
Why should the &&= assignment have a different effect depending on
whether one prepends "$y ||= " to it or not?

Because that's how those operators are defined to work.

Sinan
 
P

Paul Lalli

J Krugman said:
I don't know whether this is a bug or what, but it's about the most
bizarre Perl "quirk" (to keep it printable) I've ever come across,
and I've seen my share. If I run the following Perl script:

$x = $y = 1;
$y ||= ($x &&= 0);
print "$x\n";

The output is
1

All of the OP= operators are defined so that
$x OP= $y
is equivalent to
$x = $x OP $y

Therefore, your example expands to:
$y = $y || ($x = $x && 0);

From this, it should be easy to see that since the first operand of ||
is already true, the second operand is never evaluated.

Paul Lalli
 
L

Leslie Viljoen

perl -wle 'eval {die [[qq [Just another Perl Hacker]]]};; print
${${${@}}[$#{@{${@}}}]}[$#{${@{${@}}}[$#{@{${@}}}]}]'

Abigail?
How on earth does this work?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,169
Messages
2,570,916
Members
47,458
Latest member
Chris#

Latest Threads

Top