Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Wondering about returned regex special arrays on going out of scope

0 views
Skip to first unread message

Ton Hospel

unread,
Mar 4, 2004, 3:23:28 AM3/4/04
to perl5-...@perl.org
perl -wle 'sub f {"ab" =~ /(.)/; print "@+"; return @+}; print f'
1 1
Use of uninitialized value in print at -e line 1.
Use of uninitialized value in print at -e line 1.

Ok, I can sort of see what's going on here. the scope with the regex
is left, and @+ gets restored to it's old value (empty). So my result
still knows it was 2 long, but the values are gone, and I get 2 undefs.

But why didn't I get copies of the values, no longer sensitive to
their origin evaporating ?

If I try to sort of do this (as much as possible) with a normal array,
I don't observe the effect:

perl -wle 'sub DESTROY { $a[0]=1} @a="a".."c"; sub f { my $a=bless[]; return @a } print f'
abc

(I was sort of starting to expect 1bc here)

Is this weird combination of the new size with the old values what I
should have expected ?

perl -wle '"xyz"=~/(.)(.)/; print "@+"; sub f {"ab" =~ /(.)/; print "@+"; return @+} print f'
2 1 2
1 1
21

Rafael Garcia-Suarez

unread,
Mar 4, 2004, 3:50:15 AM3/4/04
to perl5-...@perl.org
Ton Hospel wrote in p5p:

> perl -wle 'sub f {"ab" =~ /(.)/; print "@+"; return @+}; print f'
> 1 1
> Use of uninitialized value in print at -e line 1.
> Use of uninitialized value in print at -e line 1.
>
> Ok, I can sort of see what's going on here. the scope with the regex
> is left, and @+ gets restored to it's old value (empty). So my result
> still knows it was 2 long, but the values are gone, and I get 2 undefs.
>
> But why didn't I get copies of the values, no longer sensitive to
> their origin evaporating ?

I think that this behaviour of @+ et alii is similar to the automatic
scoping of $1 et alii.

Ton Hospel

unread,
Mar 4, 2004, 4:02:14 AM3/4/04
to perl5-...@perl.org
In article <slrnc4drg3.8i9...@dat.local>,

Rafael Garcia-Suarez <rgarci...@free.fr> writes:
> I think that this behaviour of @+ et alii is similar to the automatic
> scoping of $1 et alii.

It's not the scoping that surprises me, that is expected.
What surprised me is that the return value isn't a copy.

Notice that this works as expected,
even though $1 also goes out of scope:

perl -wle 'sub f {"ab" =~ /(.)/; return $1}; print f'

Rafael Garcia-Suarez

unread,
Mar 4, 2004, 5:37:41 AM3/4/04
to perl5-...@perl.org
Ton Hospel wrote in perl.perl5.porters :

>
> It's not the scoping that surprises me, that is expected.
> What surprised me is that the return value isn't a copy.

Ooh, that's a bug. A strange one, a cursory inspection of the sources
makes me think that it *should* work -- the values ought to be copied,
like when you return explicitly ($+[0],$+[1]).

h...@crypt.org

unread,
Mar 5, 2004, 12:42:25 PM3/5/04
to Rafael Garcia-Suarez, perl5-...@perl.org
Rafael Garcia-Suarez <rgarci...@free.fr> wrote:
:Ton Hospel wrote in perl.perl5.porters :

Looking at the difference between pp_rv2av() and pp_aelemfast(), which
causes the difference in behaviour between C< @+ > and C< ($+[0], $+[1]) >,
the patch below may be desirable. But I really don't understand the
ramifications of it well enough to know whether it should go in.
Without this, the things put on the stack for C< return @+ > are the
magic lvals constructed in av_fetch().

No tests failed for me with this; I wonder whether it would cause problems
for anyone making heavy use of ties or other magic on arrays.

Of course if it turns out that everyone calling av_fetch(av, key, FALSE)
should be doing this, it would probably be better for av_fetch() to be
doing it itself - it can certainly do so much more efficiently. That would
probably imply spliting out an av_fetch_rval() for internal use, to avoid
breaking existing usage.

And we should probably look at pp_rv2hv in case that needs something similar.

Hugo
--- pp_hot.c.old Wed Feb 25 01:55:25 2004
+++ pp_hot.c Fri Mar 5 17:33:26 2004
@@ -778,7 +778,10 @@
U32 i;
for (i=0; i < (U32)maxarg; i++) {
SV **svp = av_fetch(av, i, FALSE);
- SP[i+1] = (svp) ? *svp : &PL_sv_undef;
+ SP[i+1] = (svp)
+ /* see note in pp_helem, and bugid ?? */
+ ? SvGMAGICAL(*svp) ? sv_mortalcopy(*svp) : *svp
+ : &PL_sv_undef;
}
}
else {

0 new messages