develooper Front page | perl.perl5.porters | Postings from June 2015

Re: [perl #125436] Experimental refaliasing with local not restoringvalues when scope exited

Thread Previous | Thread Next
From:
Dave Mitchell
Date:
June 23, 2015 11:47
Subject:
Re: [perl #125436] Experimental refaliasing with local not restoringvalues when scope exited
Message ID:
20150623114650.GC15986@iabyn.com
On Thu, Jun 18, 2015 at 07:12:12PM -0700, Ken Cotterill wrote:
> This bug relates to the experimental feature 'refaliasing' described in:
> http://search.cpan.org/~rjbs/perl-5.22.0/pod/perlref.pod#Assigning_to_References
> 
> My expectation was that using the "\local our" form would restore values when
> the scope of the 'local' was exited.
> 
> This wasn't the case and the observed behaviour was identical to using the "\our"
> form.

I don't think its a bug.

The first form is doing the equivalent of:

    @data = (1,2,3);
    {
        local @data = @data;
        @data = ();
    }

which

    * creates a temporary new array;
    * updates the symbol table so that '@data' temporarily refers to the
      new array; the original @data array is still hanging around, hidden
      on the save stack, with its original (1,2,3) elements.
    * copies the elements of the original @data to the new array;

and then
    * frees all the elements of the new temp array (i.e. the *copies* of
      (1,2,3);

and which on scope exit:

    * frees the new temporary array and any elements it contains (which is
      none in this case as we earlier cleared the array);
    * updates the symbol table to make '@data' refer again to the original
      array, which still contains the original (1,2,3).


The second form is doing the equivalent of:

    @data = (1,2,3);
    {
        \local @data = \@data;
        @data = ();
    }

which

    * temporarily saves the old pointer to @data in the symbol table
      on the save stack, then makes the entry point to the thing on the
      RHS, which in this case, is @data: i.e. the entry in the symbol
      table still points to the *same* array;

and then
    * frees all the elements of the @data array (i.e. the original and only
      array)

and which on scope exit:

    * restores the pointer in the symbol table to its original value
      (which since they're the same, is a no-op in this case);
    * so '@data' still refers to the array which we've just emptied.

Note that if you did something like

    @data = (1,2,3);
    {
        \local @data = [4,5,6];
        @data = ();
    }

then @data *would* contain (1,2,3) at the end.

Or to put it another way,

    \local @data = \XXX

localises the symbol table entry to whatever XXX is, while

    local @data = XXX

localises the symbol table entry to a new array, and then populates the
new array with the elements of XXX.

(In the above, whenever I've referred to 'symbol table entry', technically
I've meant AV slot of the GV referenced from the 'data' entry in the
%main:: symbol table).

-- 
I thought I was wrong once, but I was mistaken.

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