develooper Front page | perl.perl5.porters | Postings from March 2000

Re: Exotic bug in local?

Thread Previous | Thread Next
From:
Jan Dubois
Date:
March 23, 2000 00:58
Subject:
Re: Exotic bug in local?
Message ID:
0pmjdsc2elk86hl2047tj7o63qtgkvkqqj@4ax.com
On Wed, 22 Mar 2000 22:02:37 -0700, Tom Christiansen
<tchrist@chthon.perl.com> wrote:

>PS:
>
>>    % perl -le '@a = 1..10; { local $#a = 4; print @a; } print @a'
>>    12345
>>    12345
>
>    Assigning to `$#days' actually changes the length of the array.
>    Shortening an array this way destroys intervening values.
>    Lengthening an array that was previously shortened does not
>    recover values that were in those elements.
>
>I can understand that it destroys them if you say
>
>    $#a = 4;
>
>But I don't understand why it pretends not have seen the local().

Because pp_av2arylen doesn't check the OPpLVAL_INTRO flag.  It basically
ignores localization.  But then again, what could it possibly do? $#a is
magical; assigning to it calls av_fill() on @a.  How should this be
undone?  The best thing it could do would be to set $#a to 9 again,
filling the additional slots with undef.  Your code above wouldn't see the
difference. 

As a simple hack I tried adding the following two lines to pp_av2arylen:

    if (PL_op->op_private & OPpLVAL_INTRO)
	save_svref(&AvARYLEN(av));

directly in front of the

    SETs(sv);

Of course this will undef $#a before setting it to 4, so it doesn't work.
And it wouldn't be correct, because the refcount of @a should be
incremented/decremented too while a new reference to $#a exists.  I guess
it should just be documented, that $#a cannot be localized.

Using local() on magical entities generally doesn't work too well (e.g.
local on tied hashes).  It would need corresponding entries in the magic
VTBL to do the save/restore stuff.

-Jan

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About