Stop values from ‘sticking’ to @- and @+ elems
These arrays are very similar to tied arrays, in that the elements are
created on the fly when looked up. So push @_, \$+[0], \$+[0], will
push references to two different scalars on to @_.
That they are created on the fly prevents this bug from showing up
in most code: If you reference the element you can observe that, on
FETCH, it gets set to the corresponding offset *if* the last match has
a set of capturing parentheses with the right number. Otherwise, the
value in the element is left as-is.
So, doing another pattern match with, say, 5 captures and then another
with fewer will leave $+[5] and $-[5] holding values from the first
match, if there is a FETCH in between the two matches:
$ perl -le '" "=~/()()()()(..)/; $_ = \$+[5]; print $$_; ""=~ /()/; print $$_;'
2
2
And attempts at assignment will succeed, even though they croak:
$ perl -le 'for ($-[0]) { eval { $_ = *foo }; print $_ }'
*main::foo
The solution here is to make the magic ‘get’ handler set the SV
no matter what, instead of just setting it when it refers to a
valid offset.