This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Fix ()=@a=split
authorFather Chrysostomos <sprout@cpan.org>
Sun, 12 Oct 2014 00:17:32 +0000 (17:17 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 12 Oct 2014 01:41:24 +0000 (18:41 -0700)
commitafc80078650f4c5361caace3f0ae6c934135d0ec
treec58ab68abe1dfc0dcfb0bb25eb44abd2df8ed126
parent7bb1ed39649da5f23a3103922cedbb4e3cd82856
Fix ()=@a=split

@a=split//,$foo gets optimised such that split writes directly to
the array and the list assignment doesn’t happen.  In fact, the list
assignment is completetly removed from the op tree:

$ ./perl -Ilib -MO=Concise -e '@a=split//,$foo'
7  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v:{ ->3
6     <@> split[t2] vK/IMPLIM ->7
3        </> pushre(/""/ => @a) s/RTIME ->4
-        <1> ex-rv2sv sK/1 ->5
4           <$> gvsv(*foo) s ->5
5        <$> const(IV 0) s ->6
-e syntax OK

(There would have been aassign where you see split if the optimisation
had not happened.)

($a,$b,$c) = split... optimises split by setting its limit argument
automatically so it doesn’t bother splitting into more parts than
necessary.

The latter optimisation was doing the wrong thing for () = @a = split,
because the @a=split on the rhs was being optimised down to a split
op.  Then the limit optimisation would see an empty (or short) list on
the lhs and a split op on the rhs and see it as a candidate for lim-
ited split.  So too few items would be assigned to the array.

We need to check whether the split on the rhs is a split-to-array
first before doing the limit optimisation.  (If it is, then don’t
optimise.)

This breaks one of my JAPHs:

()=@==split" ","Just another Perl hacker,\n";
print reverse@=
op.c
t/op/split.t