XP is just a number PerlMonks

### Why Perl boolean expression sometimes treated as lvalue?

by vsespb (Chaplain)
 on Feb 08, 2013 at 11:28 UTC Need Help??
vsespb has asked for the wisdom of the Perl Monks concerning the following question:

In continue of this http://www.perlmonks.org/?node_id=1017390 discussion
```my \$a = 1;
my \$b = 2;
\$a && \$b = 3;
this does not work. good. but this
```use strict;
use warnings;
sub a
{
\$_[0] = 3;
}
my \$x = 0;
my \$y = 5;
a(\$x && \$y);
print "\$x\n";
prints 3 (because \$x aliased as 1-st arg to subrouting), so \$x && \$y works as lvalue. I wonder why so ? I didn't find documentation for this (not in perlsub/perlop)

Replies are listed 'Best First'.
Re: Why Perl boolean expression sometimes treated as lvalue?
by Athanasius (Chancellor) on Feb 08, 2013 at 12:24 UTC

In Perl, arguments are passed by reference, not by value. This is what perlsub means when it says: “The array @_ is a local array, but its elements are aliases for the actual scalar parameters.”

The subroutine call a(\$x && \$y) causes the Perl interpreter to evaluate the boolean expression \$x && \$y to determine which variable is to be aliased. If \$x is false, the expression short-circuits, so a reference to \$x is passed in to the sub; but if \$x is true, short-circuiting does not occur, and so it is a reference to \$y that is passed in to the sub.

So it is misleading to say that the boolean expression works as an l-value. Within sub a, the boolean expression is never seen — only the reference to either \$x or \$y — and it is this reference which works as an l-value.

I haven’t found anything in the documentation to explain the process by which Perl derives a reference (“alias”) from a complex expression given as an argument to a subroutine. It might be useful to know — but, in general, it’s safer and clearer to keep things simple and just pass a variable or a value.

Hope that helps,

 Athanasius <°(((>< contra mundum Iustus alius egestas vitae, eros Piratica,

perlop perlop perlop , precedence is everything :)

```\$ perl -E " print ( 1 && 2 )
2

\$ perl -E " sub ff { ++\$_[0] } my(\$f,\$a)=(1,5); ff( \$f && \$a ); say \$f
+; say \$a; "
1
6
Re: Why Perl boolean expression sometimes treated as lvalue?
by tobyink (Abbot) on Feb 08, 2013 at 13:28 UTC

Hmmm... interesting disparity. The following may be of interest...

```use v5.10;

my (\$a, \$b) = (0, 0);

sub lv :lvalue { \$_[0] }

lv(\$a || \$b) = 2;
lv(\$a && \$b) = 1;

say \$a;
say \$b;
package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
Re: Why Perl boolean expression sometimes treated as lvalue?
by vsespb (Chaplain) on Feb 08, 2013 at 12:22 UTC
Well, seems this example makes more sense.
```my \$a = 0;
my \$b = 2;
my \$z = \(\$a && \$b);
\$\$z = 4;
print \$a;
(prints 4)

Interesting ... note the parens, perl parses it correctly

```\$ perl -MO=Deparse,-p -le " \$a= 1 && 2; print \$a; "
BEGIN { \$/ = "\n"; \$\ = "\n"; }
(\$a = 2);
print(\$a);
-e syntax OK

\$ perl -MO=Deparse,-p -e "  \$a && \$b = 3; "
Can't modify logical and (&&) in scalar assignment at -e line 1, near
+"3;"
((\$a && \$b) = 3);

But there is no code to execute this :) its default Can't modify %s http://perl5.git.perl.org/perl.git/blob?f=op.c#l2020

```
2012         /* FALL THROUGH */
2013     default:
2014       nomod:
2015         if (flags & OP_LVALUE_NO_CROAK) return NULL;
2016         /* grep, foreach, subcalls, refgen */
2017         if (type == OP_GREPSTART || type == OP_ENTERSUB
2018          || type == OP_REFGEN    || type == OP_LEAVESUBLV)
2019             break;
2020         yyerror(Perl_form(aTHX_ "Can't modify %s in %s",
2021                      (o->op_type == OP_NULL && (o->op_flags & OPf
+_SPECIAL)
2022                       ? "do block"
2023                       : (o->op_type == OP_ENTERSUB
2024                         ? "non-lvalue subroutine call"
2025                         : OP_DESC(o))),
2026                      type ? PL_op_desc[type] : "local"));
Re: Why Perl boolean expression sometimes treated as lvalue?
by ikegami (Pope) on Feb 11, 2013 at 04:31 UTC

Quite simply:

• \$y always returns the scalar, not a copy of it.
• && always returns the scalar its LHS returned or the scalar(s) its RHS returned, not a copy of it.

That's it. Why isn't it documented that they don't make a copy in rvalue context? Why would it.

If you wanted to explicitly copy the scalar, you could do a( 0+( \$x && \$y ) ). Then, \$_[0] = 3; will modify the anonymous scalar the addition constructed.

You're missing the point

If so, your message does not help. Please clarify the question if you think I didn't understand it.

Create A New User
Node Status?
node history
Node Type: perlquestion [id://1017801]
Approved by vinoth.ree
Front-paged by RMGir
help
Chatterbox?
 [ELISHEVA]: but it seems that the DBD::CSV layer on top of it doesn't [afoken]: Also: All other attributes that start with csv_ and are not described above will be passed to Text::CSV_XS (without the csv_ prefix). [Discipulus]: what about a good 'ol SOPW? [erix]: Giro d'Italia won by Dumoulin (peccato Nibali) [ELISHEVA]: csv_detect_bom doesn't work either [erix]: (SCNR) [ELISHEVA]: I may have to resort to SOPW - but was hoping that this would be something simple [erix]: I'd just remove the BOM, it is pretty simple [ELISHEVA]: Simple yes. and I did consider that. but this isn't one off . An important data source that I don't control is generating bom prefixed utf8 files and I'd rather not have to be munging files every few months. [erix]: on teh other hand a SOPW is pretty much garanteed to get an answer from tux (and probably the module fixed)

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (7)
As of 2017-05-28 20:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
My favorite model of computation is ...

Results (192 votes). Check out past polls.