Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

local our $var; What does it do?

by kcott (Archbishop)
on Jun 18, 2015 at 08:56 UTC ( [id://1130948]=perlquestion: print w/replies, xml ) Need Help??

kcott has asked for the wisdom of the Perl Monks concerning the following question:

G'day All,

I'm reading through the perldelta for v5.22.0 and have twice come across code like:

local our $var;

Aliasing via reference has a link to perlref: Assigning to References which has:

\local our $scalar # etc.

Updated Modules and Pragmata (under B::Deparse) has:

local our is now deparsed correctly, with the our included.

When I hit it the first time, I thought it was new in v5.22.0: I couldn't recall seeing it previously and assumed I'd be enlightened further down the document.

Given the second hit (which I've just come across) is an update, it's clearly not new in v5.22.0.

I've searched for the string 'local our' in (CPAN v5.22.0 versions of) perlfunc, perlsub and perlref but can't find a match (except for the \local our $scalar already mentioned).

If someone could provide a link to where this is documented, that would be great.

Failing that, can anyone explain what it does.

Thanks in advance.

-- Ken

Replies are listed 'Best First'.
Re: local our $var; What does it do?
by BrowserUk (Patriarch) on Jun 18, 2015 at 09:20 UTC

    It's equivalent to:

    our $var; local $var;

    The first line makes the global $var name visible at the current scope with use strict vars.

    The second line localises it in the normal way.

    Presumably aimed at simplifying aliasing. As in:

    sub sum { our @a local *a = shift; my $total = 0; $total += $a[ $_ ] for 0 .. $#a; return $total; } my @data = getNums(); my $sum = sum( \@data );

    Which is nicer than:

    sub sum { my $aref = shift; my $total = 0; $total += $aref->[ $_ ] for 0 .. $#{ $aref }; return $total; } my @data = getNums(); my $sum = sum( \@data );

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
    In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

      And with the new refaliasing feature, as I understand it, that becomes:

      use v5.22; use feature 'refaliasing'; no warnings 'experimental::refaliasing'; sub sum { \local our @a = shift; my $total = 0; $total += $a[ $_ ] for 0 .. $#a; return $total; }
        our @a; local *a = shift;

        can be safely rewritten as

        \local our @a = shift;

        but you'd normally want

        \my @a = shift;

        since the only reason package variables were used is because lexical variables couldn't be aliased like that.

        That means the code should really become

        sub sum { \my @a = shift; my $total = 0; $total += $a[ $_ ] for 0 .. $#a; return $total; }

        So we loose one line at the point of use; and add 3 at the top of the code. That's progress :)


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
        In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

      Thanks for the explanation and examples.

      I believe I'm completely across this now.

      -- Ken

Re: local our $var; What does it do? (quiets strict)
by Anonymous Monk on Jun 18, 2015 at 09:16 UTC

    It quiets strict so you can use short names instead of fully qualified names

    $ perl -Mstrict -we " local $fudge = 12; " Global symbol "$fudge" requires explicit package name at -e line 1. Execution of -e aborted due to compilation errors. $ perl -Mstrict -we " local our $fudge = 12; "

    See local our?

    I've also seen it here https://perl.apache.org/docs/1.0/guide/porting.html

    Turning regular "cgi" into registry is most often where I've seen "local our" because folks don't want to grok my lexicals

      Thanks for the explanation and links.

      Clearly nothing new at all: I'm somewhat surprised I haven't encountered it before.

      -- Ken

Re: local our $var; What does it do? (\local our: [perl #125436])
by kcott (Archbishop) on Jun 18, 2015 at 12:19 UTC

    Having got a handle on 'local our', here's an example showing that compared with '\local our'.

    #!/usr/bin/env perl use 5.022; use warnings; use feature 'refaliasing'; no warnings 'experimental::refaliasing'; @::data = (1 .. 3); say "Data before pop_sum: @::data"; say "Sum of data: ", pop_sum(\@::data); say "Data after pop_sum: @::data"; say '---'; say "Data before pop_sum_ref: @::data"; say "Sum of data: ", pop_sum_ref(\@::data); say "Data after pop_sum_ref: @::data"; sub pop_sum { local our @data = @{+shift}; my $total = 0; say "\tTotal: $total; Data: @data"; while (1) { $total += pop @data; say "\tTotal: $total; Data: @data"; last if $#data < 0; } return $total; } sub pop_sum_ref { \local our @data = shift; my $total = 0; say "\tTotal: $total; Data: @data"; while (1) { $total += pop @data; say "\tTotal: $total; Data: @data"; last if $#data < 0; } return $total; }

    Output:

    Data before pop_sum: 1 2 3 Total: 0; Data: 1 2 3 Total: 3; Data: 1 2 Total: 5; Data: 1 Total: 6; Data: Sum of data: 6 Data after pop_sum: 1 2 3 --- Data before pop_sum_ref: 1 2 3 Total: 0; Data: 1 2 3 Total: 3; Data: 1 2 Total: 5; Data: 1 Total: 6; Data: Sum of data: 6 Data after pop_sum_ref:

    So, with 'local our', we can do whatever we want with @data and, once local's scope is exited, @::data gets back its previous values. As we'd expect with local.

    However, the usefulness of '\local our' in this scenario eludes me. @::data does not get back its previous values. Changing

    sub pop_sum_ref { \local our @data = shift;

    to

    sub pop_sum_ref { \our @data = shift;

    produces exactly the same results.

    Perhaps it simply not useful in this scenario. Perhaps its not operating as intended.

    Update: I've raised a bug report for the \local our issue. I'll update again when I get a ticket number.

    Update2: Got the ticket: [perl #125436]

    For those wishing to view this, there may be some issues.

    I used the perlbug utility, which appeared to run successfully:

    Message sent Thank you for taking the time to file a bug report! Please note that mailing lists are moderated, your message may take a while to show up. If you do not receive an automated response acknowledging your message within a few hours (check your SPAM folder and outgoing mail) please consider sending an email directly from your mail client to perlbug@perl.org.

    I waited about 10 hours, received no automated response, so followed the above advice and emailed directly.

    Thunderbird somehow mangled what was sent: multiple instances of embedding font tags dozens of levels deep. All you'll initially see is:

    "Message body is not shown because it is too large."

    If you really want to, you can download the text/html content (31.3k) and view it in a browser. However, other than my perl -V output, it mostly contains the same content as you'll find in this thread, so there's little point in doing this unless you really are that interested.

    -- Ken

      However, the usefulness of '\local our' in this scenario eludes me. @::data does not get back its previous values.

      In that case, as a feature, it still needs work, because it doesn't produce the same results as the existing syntax its intended to simplify:

      our @data = 'fred'; sub x{ our @data; local *data = shift; print $data[ $_ ] for 0 .. $#data; };; my @junk = reverse 1 .. 10; x( \@junk ); print ">>@data<<<";; 10 9 8 7 6 5 4 3 2 1 >>fred<<<

      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
      In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

        Thanks for reviewing. I've raised a bug report.

        -- Ken

Re: local our $var; What does it do?
by ikegami (Patriarch) on Jun 18, 2015 at 16:59 UTC

    our $foo aliases $foo to $CURRENT_PACKAGE::foo.

    local $foo backs up the value of $foo and causes the backup to be restored when the current lexical scoped it existed.

    our $foo returns $foo, so local our $foo is the same as our $foo; local $foo.

    Basically local our $foo the closest approximation possible of my $foo, but using package variables instead of lexical variables. I have no idea why you'd want to do that.


    Update: I previously had an example that used local our @ARGV = @args;, but that should be just local @ARGV = @args;.

      Thanks for the explanation ...

      ... which has grown since I hit [reply] — obviously you're still typing.

      Thanks in advance for any more you type; but I can only upvote once. :-)

      Update: Oh dear, it's shrunk back to almost it's original size. I'll go away and make a cup of tea and wait for this dynamic post to reach a state of quiescence. :-)

      -- Ken

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1130948]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (3)
As of 2024-04-19 22:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found