Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

Re: Referencing localized variables, and typeglobs

by AnomalousMonk (Chancellor)
on Aug 30, 2017 at 23:27 UTC ( #1198370=note: print w/replies, xml ) Need Help??

in reply to Referencing localized variables, and typeglobs

With reference only to the first part of your OPed question, I agree with Laurent_R's explanations here and here.

Here's another way to think about the issue that might offer some confidence and comfort, for all it's long-windedness. (I don't doubt that you understand all this perfectly well, but perhaps someone else may benefit from this blatheration.) With reference to the OPed code:

  • A simple
        do { local %h; }
    expression saves the original content of the package variable referenced by the  %h symbol and default-initializes a new storage location with the same symbolic name within the scope of the do expression. This new storage location is entirely separate from and independent of the storage location originally associated with the  %h symbol prior to the execution of the local statement in the do-expression. At the end-of-scope of the do-expression, any new storage space allocated within the scope of the do-expression is released (because there is no further reference to it) and the  %h symbol reverts to its old, saved symbolic referent.
  •     do { local %h = (a => '3'); }
    does the same and then explictly initializes the new storage location. Again, the newly initialized storage is released at the end-of-scope of the do-expression because there is no longer any reference to it.
  •     do { local %h = (a => '3');  \%h; }
    further takes the reference address of the new (and newly initialized) storage location. The do-expression now evaluates to this reference address, but if nothing more is done with the reference address, nothing can ever access the new storage created within the do-expression and this storage is released and (eventually) garbage-collected.
  • The complete statement
        my $x = do { local %h = (a => '3');  \%h; };
    does save the reference address produced by evaluation of the do-expression, so the storage just created within the scope of the do-expression cannot be released. (However, the  %h symbol still "snaps back" at the end-of-scope of the do-expression.) The reference address produced by evaluation of the do-expression survives, and the storage space associated with it will only be released once all copies of this reference to it (e.g., the  $x variable) have passed out of scope.
Looking at the differing reference addresses of the various storage locations created by your original code example may also be convincing:
c:\@Work\Perl\monks>perl -wMstrict -MData::Dump -le "print 'perl version: ', $]; ;; our %h; ;; my $x = do { local %h=(a=>'3'); \%h }; my $y = do { local %h=(b=>'5'); \%h }; ;; print 'ref. addr. of %h: ', \%h; dd 'contents of %h: ', \%h; ;; print 'ref. addr. of $x: ', $x; dd 'contents of $x: ', $x; ;; print 'ref. addr. of $y: ', $y; dd 'contents of $y: ', $y; " perl version: 5.008009 ref. addr. of %h: HASH(0x2c068a4) ("contents of %h: ", {}) ref. addr. of $x: HASH(0x14b5fa4) ("contents of \$x: ", { a => 3 }) ref. addr. of $y: HASH(0x14b60dc) ("contents of \$y: ", { b => 5 })
(Note that this example was run under Perl 5.8.9.)

... I'm wondering if it's "safe" ...

Yes, Dr. Szell, it's perfectly safe.

Give a man a fish:  <%-{-{-{-<

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1198370]
and the universe expands...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (8)
As of 2017-10-24 08:17 GMT
Find Nodes?
    Voting Booth?
    My fridge is mostly full of:

    Results (286 votes). Check out past polls.