Re: ... for (@_) x= 2;
by 1nickt (Canon) on Dec 28, 2015 at 21:20 UTC
|
x= , the repetition assignment operator, only works on scalars.
So you can do:
my $str = 'ab';
$str x= 2;
print $str;
# 'abab'
You don't say what you want as output, but maybe you are looking for:
#!/usr/bin/perl
use warnings;
use strict;
$\ = $/;
@_ = ( 'a' .. 'b' ) x 2;
print for @_;
Output:
a
b
a
b
edit: show example of repetition assignment on a scalar
The way forward always starts with a minimal test.
| [reply] [d/l] [select] |
|
Yes, firstly, I wanted so for an output, but later I found that behaviours are interesting with using 'x=' operator :) . I experimented if I can multiply the array in 'for' sentence with using 'x='.
| [reply] |
|
perl -le'print map $_ x=2, ("a" .. "f")'
jeffa
L-LL-L--L-LL-L--L-LL-L--
-R--R-RR-R--R-RR-R--R-RR
B--B--B--B--B--B--B--B--
H---H---H---H---H---H---
(the triplet paradiddle with high-hat)
| [reply] [d/l] |
Re: ... for (@_) x= 2;
by GrandFather (Saint) on Dec 28, 2015 at 21:59 UTC
|
I suspect the key is that x= only operates on scalars. So (@_ = ('a' .. 'b')) is in scalar context and becomes the scalar value 2 which x then make two of.
Premature optimization is the root of all job security
| [reply] [d/l] |
|
| [reply] [d/l] [select] |
Re: ... for (@_) x= 2; (scalar assignment)
by LanX (Sage) on Dec 28, 2015 at 23:23 UTC
|
I had problems to understand what your goal is, this code already looks broken.
It's true that x has a double nature (repeat string vs repeat list) like .. depending on context (flip flop vs range)
But "combined assignments" like += only allow scalars on the LHS...
See perlop
> These combined assignment operators can only operate on scalars, whereas the ordinary assignment operator can assign to arrays, hashes, lists and even references.
update
Besides you don't need any assignment
print for @_ x 2 should already work perfectly.
update
correction print for (@_) x 2 should already work perfectly.
DB<100> @_=1..3
=> (1, 2, 3)
DB<101> print for @_ x 2
=> ""
33
DB<102> print for (@_) x 2
=> ""
123123
from perlop
> In list context, if the left operand is enclosed in parentheses or is a list formed by qw/STRING/, it repeats the list.
| [reply] [d/l] [select] |
|
I supposed that three of my codes looks equivalently (for me), so and output should be the same - e.g. warning + compilation error.
| [reply] |
|
the list assignment returns the length of the list in scalar context, so
DB<114> $l = ( @a = qw/a b/ )
=> 2
So it's not the same code!
The difference between your code and my example is that there is no explicit variable (like $l) used here, but somehow it's still possible to change it.
Maybe it's a side effect of for ? I dunno.
I'd prefer a Can't modify warning here too!
But it's still a very peculiar construction, so I'm not surprised if this edge case wasn't covered.
HTH!
update
More insights:
... it's not the temporary scalar which is modified but the resulting list in brackets
DB<121> print "$_\n" for ($a=666) x= 2
666
666
=> ""
DB<122> $a
=> 666
According to the already cited documentation of "combined assignments" this shouldn't be possible, b/c its a list operation. | [reply] [d/l] [select] |
|
|
|
LanX cited: "> In list context, if the left operand is enclosed in parentheses or is a list formed by qw/STRING/, it repeats the list."
Now I tried to write some lines with 'qw' and found next interesting situation, which I can't understand:
#!/usr/bin/perl
use warnings;
use strict;
$\ = $/;
$, = '+';
print qw/a b/ x 2;
print scalar(qw/a b/ x 2);
print for (qw/a b/ x 2) x 2;
print for qw/a b/ x 2 x 2;
OUTPUTS:
a+b+a+b
bb
a
b
a
b
a
b
a
b
bbbb
The strange for me is the output of second 'print' (of course so does 4th too): it prints "bb" instead of supposed "b". I don't catch that, because print scalar('a','b','a','b'); would print "b". | [reply] [d/l] [select] |
|
| [reply] |
|
|
|
Re: ... for (@_) x= 2;
by Anonymous Monk on Dec 28, 2015 at 23:48 UTC
|
$ perl -E '$x = "foo"; say for $x x= 2'
that compiles to (only relevant part):
BINOP (0x189a938) repeat [1]
UNOP (0x189a9c0) null [15]
SVOP (0x189aa00) gvsv GV (0x197dac8) *x
SVOP (0x189a980) const IV (0x197dae0) 2
while
$ perl -E '$x = "foo"; say for ($x) x= 2'
is actually
BINOP (0xecd938) repeat [1]
UNOP (0xecd8f0) null [158]
OP (0xecd8b8) pushmark
UNOP (0xecd9c0) null [15]
SVOP (0xecda00) gvsv GV (0xfb0ac8) *x
SVOP (0xecd980) const IV (0xfb0ae0) 2
and
$ perl -E '@x = (@_ = qw( a b )) x= 2'
is
BINOP (0x14b79b8) repeat [4]
UNOP (0x14b7970) null [158]
OP (0x14b7938) pushmark
BINOP (0x14b7a40) aassign [3]
UNOP (0x14b7b40) null [158]
OP (0x14b7b08) pushmark
SVOP (0x13ffc38) const PV (0x159ab28) "a"
SVOP (0x13ffbe0) const PV (0x159ab70) "b"
UNOP (0x14b7ac0) null [158]
OP (0x14b7a88) pushmark
UNOP (0x13ffc78) rv2av [2]
SVOP (0x13ffcb8) gv GV (0x13de0d0) *_
SVOP (0x14b7a00) const IV (0x159ab58) 2
So pretty much like GrandFather said. Hopefully that answers your question. I don't think it's documented anywhere; see toke.c and perly.y if you want more details. Certainly this behaviour is subject to change without notice. | [reply] [d/l] [select] |