&& is not an lvalue

X

xhoster

It seems like almost everything in Perl is an lvalue. So why isn't the
result of && an lvalue?

I wanted to do this:
($h{$big}{$nasty}[$dereferencing]{operation($x)}{$done}[here(y)]and die)=6;


Obviously, that just isn't the way perl was implemented. But is there a
reason that "?:" yields an lvalue but && doesn't?

Thanks,

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 
B

Ben Morrow

Quoth (e-mail address removed):
It seems like almost everything in Perl is an lvalue. So why isn't the
result of && an lvalue?

I wanted to do this:
($h{$big}{$nasty}[$dereferencing]{operation($x)}{$done}[here(y)]and die)=6;

Obviously, that just isn't the way perl was implemented. But is there a
reason that "?:" yields an lvalue but && doesn't?

Perhaps because it's not entirely clear which operand would be returned
when both are true or both false? That doesn't apply to your case, of
course, since one of them is 'die' and can never be returned, but perl
doesn't know that.

Which one you actually get is rather confusing. If either is false, you
get that one; if both are false, you get the first; and if both are
true you get the second. || is the other way around: both false gives
the second operand, and both true the first. I suppose it makes sense
when you consider the short-circuiting.

Oddly, you *can* take a ref to the result of && (which is in fact an
lvalue), which means

${\( $x and die )} = 6;

*does* work as you expect, despite being hideously ugly.

Even stranger, while do { $x } returns $x (though of course you can't
assign to it directly), if the expression inside the 'do' gets too
complicated it starts returning a copy instead:

~% perl -le'print \do { $x }; print \$x'
SCALAR(0x8100be0)
SCALAR(0x8100be0)
~% perl -le'print \do { $x and 1 }; print \$x'
SCALAR(0x8100be0)
SCALAR(0x8100be0)
~% perl -le'print \do { $x and die }; print \$x'
SCALAR(0x810016c)
SCALAR(0x8100be0)
~% perl -le'print \do { $x; $x }; print \$x'
SCALAR(0x810016c)
SCALAR(0x8100be0)

The point at which it switches over appears to be when the do block gets
its own ENTER/LEAVE ops rather than just being a scope.

A clean way around the problem is to use Data::Alias:

use Data::Alias;

alias my $tmp = $h{......}
and die ...;
$tmp = 6;

Ben
 
M

Michael Carman

Ben said:
Quoth (e-mail address removed):

Perhaps because it's not entirely clear which operand would be
returned when both are true or both false?

&& is defined to return the last thing evaluated. How is that not clear?
Which one you actually get is rather confusing.

I don't think that the behavior of the operator isn't confusing at all.
Any code that makes use of that behavior is likely to be if only because
it's so rarely used.

-mjc
 
X

xhoster

Ben Morrow said:
Quoth (e-mail address removed):
It seems like almost everything in Perl is an lvalue. So why isn't the
result of && an lvalue?

I wanted to do this:
($h{$big}{$nasty}[$dereferencing]{operation($x)}{$done}[here(y)]and
die)=6;

Obviously, that just isn't the way perl was implemented. But is there
a reason that "?:" yields an lvalue but && doesn't?

Perhaps because it's not entirely clear which operand would be returned
when both are true or both false? That doesn't apply to your case, of
course, since one of them is 'die' and can never be returned, but perl
doesn't know that.

Which one you actually get is rather confusing. If either is false, you
get that one; if both are false, you get the first; and if both are
true you get the second. || is the other way around: both false gives
the second operand, and both true the first. I suppose it makes sense
when you consider the short-circuiting.

Yep. And I was consider short-circuiting, so I didn't find it all that
confusing. Off the top of my head, I can't think if anything I'd use this
for that didn't have a die as the second. (but I probably wouldn't use
that construct in anything except one-offs or one-liners, anyway.)
Oddly, you *can* take a ref to the result of && (which is in fact an
lvalue), which means

${\( $x and die )} = 6;

*does* work as you expect, despite being hideously ugly.

Yeah, I did that experiment myself. But I didn't make the valid deduction
that you have, that it actually is an l-value, just an l-value which
the compiler pitches a fit over. Which makes it even stranger to me.
It seems like the programmers must have went out of their way to make
this syntax error happen, rather than it being a natural consequence of
something else.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 

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
473,754
Messages
2,569,527
Members
44,997
Latest member
mileyka

Latest Threads

Top