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

Could someone enlighten me about the use of local our. Where and why would I use
local our $bob = 'bob';
is a program, if it should ever be used.
-- gam3
A picture is worth a thousand words, but takes 200K.

Replies are listed 'Best First'.
Re: local our?
by ikegami (Patriarch) on Apr 04, 2006 at 21:54 UTC
    local and our are completely unrelated. For now, let's expand the code and look at the statements individually.
    our $bob; local $bob; $bob = 'bob';
    • our $bob; disables use strict 'vars' for $bob for the remainder of current scope. It allows you to use package variable $bob without its package name where you might have had to without our $bob;. [Note that this is a bit of an oversimplification. (Upd)]

    • local $bob; saves the current value of $bob (and sets $bob to undef). When the scope is exited (whether normally or by exception), $bob reclaims the value saved by local $bob.

    • $bob = 'bob'; assigns a value to $bob.

    Now, let's put these into context.

    Say you wish to take advantage of dynamic scoping. That means you need to use a package variable, not a lexical (my) variable. To avoid having to specify the package name when using that package variable, you use our. Let's also say you wish to protect the value that's currently being held by this variable. local would be used.

    Why would you want to use dynamic scoping? Maybe you want to override a global option temporarily. For example,

    use strict; use warnings; package MyModule; sub do_it { my ($arg) = @_; our $VERBOSE; ... warn(...) if $VERBOSE; ... } sub do_it_quietly { my ($arg) = @_; our $VERBOSE; # Avoid saying $MyModule::VERBOSE local $VERBOSE; # Save existing value. $VERBOSE = 0; # Disable logging. do_it($arg); } 1;

    Finally, since local and our return their arguments as lvalues, it's possible to chain these functions. For example, the following are all equivalent:

    • our $VERBOSE; local $VERBOSE; $VERBOSE = 0;
    • our($VERBOSE); local($VERBOSE); $VERBOSE = 0;
    • local(our($VERBOSE)) = 0;
    • local our $VERBOSE = 0;
      local and our are completely unrelated.

      That's not true. local is about aliasing package globals, and our creates a package global in the package where that declaration occurs (and a lexical alias to that in the current scope), so they are related: they both act upon slots in the symbol table of a package. So they are related.

      $ perl -E 'package Foo; local our $bar; package main; say for keys %Fo +o::' bar

      and

      $ perl -E 'our $bar = "foo"; say "1: $bar"; package Foo; { local our $ +bar = "quux"; say "2: $bar"; }; say "3: $bar"; package main; say "4: +$bar"; say "Foo::$_" for keys %Foo::' 1: foo 2: quux 3: foo 4: foo Foo::bar
      perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

        The fact that they both can take a package variables as an argument doesn't make them related in any meaningful way.

        local is about aliasing package globals

        No. For example, my %h; local $h{x};. It's about making temporary backups of some values.

        our creates a package global

        No. our creates a lexical variable (that's aliased to the specified package variable).

        Simply mentioning the package var is what creates it.

        $ perl -le' print $::{var} // "[undef]"' [undef] $ perl -le'$var; print $::{var} // "[undef]"' *main::var
        I think it's important to stay accurate:

        > our creates a package global in the package where that declaration occurs

        our will create a new STASH entry only, iff it doesn't already exist and it will not touch the value.

        > local is about aliasing package globals

        I can't see any "aliasing" process here, it's still the same underlying package variable.

        what do you call an "alias" here when doing local $main::bob; ?

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      > disables use strict vars for $bob for the remainder of current scope.

      this is misleading, no strict "vars" has a different effect.

      { local our $bob; #no strict 'vars'; $bob = "bob"; warn "$bob\n"; # > bob package OTHER; warn "$bob\n"; # > bob }

      { #local our $bob; no strict 'vars'; $bob = "bob"; warn "$bob\n"; # > bob package OTHER; warn "$bob\n"; # ERR: Use of uninitialized value $OTHER::bob in concatenation }

      > local and our are completely unrelated.

      well not completely, since local can't be used for private vars

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      our $bob; disables use strict 'vars' for $bob for the remainder of current scope.
      For my interest, is that actually how our is implemented, or is that just your way of explaining the effect?
        > > disables use strict vars for $bob for the remainder of current scope. > For my interest, is that actually how our is implemented ...

        no, see my other answer in this thread.

        our $bob is aliasing at compile time a "simple" symbol $bob to a full qualified $__PACKAGE__::bob for the remainder of current scope.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

        I'm not sure I understand your question. I didn't mention any algorithm, so I don't see how I could have spoken of implementation. I described its function and its effect.
      Just a warning: "Finally, since local and our return their arguments as lvalues, it's possible to chain these functions" implies that

        our local $var

      should also be equivalent. It's not: Perl returns the error:

        No such class local at ..., near "our local"

      In the end,

        local our $var

      is the way to go when you need to do this.

      Thanks for your great example. I never could think of a practical use for 'our' because it never occurred to me that the same name could be declared in more than one scope and that both would refer to the same variable. This is a great solution to the problem of initializing a variable in a BEGIN block and using it in the main code.
      Bill
Re: local our?
by codeacrobat (Chaplain) on Apr 04, 2006 at 21:45 UTC
    our $bob declares the scalar variable $bob in the current package. local localizes $bob in the current code block.
    $bob = "billy"; { local our $bob = "bob"; print $bob; # prints "bob", hides the $bob from outside the block }; print $bob; # actually prints "billy", because the local scope is gone
Re: local our?
by LanX (Saint) on Apr 14, 2019 at 20:18 UTC
    our is a compile-time declaration for package variables like my for private variables.

    our is lexically aliasing $bob to $PKG::bob (the "fully qualified name")

    "Lexically" means here till the end of the surrounding scope

    PKG is the current package name, i.e. main by default.

    It's important to understand that the variable is global and won't be destroyed at the end of the scope, like with private my-variables. Only the alias is disappearing.

    local is a runtime directive to save the variables value and restore it at the end of the scope. local is the builtin mechanism to avoid global consequences to package vars. (Perl4 didn't have private my-vars, and unfortunately one "can't localize lexical variable" ³)

    > Where and why would I use

    You can write our $bob multiple times to avoid the need to write $PKG::bob inside dedicated scopes. But it won't create a new local variable like my does.

    local our $bob = 'bob'; will protect the old value from being overwritten by "bob".

    It's a shortcut for writing 2 statements our $bob;local $bob ="bob"; *)

    use strict; use warnings; use Data::Dump qw/pp dd/; $main::bob = "by"; # fully qualified global var warn "$main::bob\n"; # > by { our $bob = "tail"; # lexical alias warn "$bob\n"; # > tail } warn "$main::bob\n"; # > tail # warn "$bob\n"; # ERR: Global symbol "$bob" requires explicit package name { local our $bob = "bob"; # protect from global effects warn "$bob\n"; # > bob package OTHER; warn "$bob\n"; # > bob (still aliased to $main::b +ob ²) } warn "$main::bob\n"; # > tail

    So yes, there are circumstances where it's pretty useful to write local our $var

    HTH! =)

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

    UPDATE
    *) logical error corrected, thanks to choroba to notice the glitch.

    ²) This demonstrates an essential often ignored difference to "use vars ;"

    ³) it's unfortunate that "lexical var" is synonymously used for "private var", since like demonstrated, our has a lexical effect.

Re: local our?
by Anonymous Monk on Apr 04, 2006 at 21:42 UTC
    Use it when, otherwise, you'd use local $Foo::bob;