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

Most of the code I've grokked that has used the "our" keyword could really have gotten away with "use vars" or just "my". Most of the places people seem to use this feature are really just trying to get around warnings from "use strict". I seek some example to meditate upon in which the "our" syntax really helps improve the performance or readability of the code. Pray tell me what those examples might be!
  • Comment on Examples fo Where "our" is really needed

Replies are listed 'Best First'.
Re: Examples fo Where "our" is really needed
by merlyn (Sage) on May 04, 2005 at 22:19 UTC
Re: Examples fo Where "our" is really needed
by dave_the_m (Monsignor) on May 04, 2005 at 22:16 UTC
    "our" is designed mainly as a replacement for "use vars", which was an ugly hack. You need "our" in preference to "my" when you have a variable which needs to be accessed from more than one source file. If this isn't the case, then you're probably better off with "my".

    Dave.

Re: Examples of where "our" is really needed
by Roy Johnson (Monsignor) on May 04, 2005 at 23:26 UTC
    See also 'our' is not 'my' (it's linked from the tutorials, under variables). In short, the only advantage is if you've got a lexical variable and a global variable with the same name. my declares a variable and its scope. our declares the scope in which a name refers to a global variable. A subsequent my would override a previous our, and a subsequent our would override a previous my.

    Of course, if you override a my at the same level, you've effectively pushed it out of scope. You can't reach that variable anymore. I don't know whether Perl itself considers it an end of scope, though.

    If, instead of replacing it with our, use vars had been upgraded to a real, scoping pragma, then there could have been a no vars to declare the end of global scope, and you'd get your lexical back.


    Caution: Contents may have been coded under pressure.
Re: Examples fo Where "our" is really needed
by Joost (Canon) on May 04, 2005 at 22:50 UTC
    AFIAK the only reason to use our() instead of use vars is that it's cleaner to restrict access global variable to some limited scope(s) where you intend to use them: use vars opens up the access till the end of file the package.

    In other words - the scoping of our() is the only difference compared to use vars.

    my is different in that lexicals aren't coupled to a package and therefore need extra work if you want access to them from another file.

    update:

    As for the performance of our() vs vars() vs my () - AFAIK lexicals are always faster than globals - provided you have direct access to them - since package globals require a hashtable lookup and lexicals are in an array of which the index is computed at compile time.

    My conclusion:

    You are probably right that most uses of package variables are gratuitous and could be replaced with lexicals without any trouble.

    However, if you need access to variables from another file, or are interfacing with XS code, and you're sure that you really only need one instance of that specific variable, a package variable can be easier and more efficient than a lexical.

      lexicals are always faster than globals - provided you have direct access to them - since package globals require a hashtable lookup
      package variables do not require a hash table lookup; each relevant op contains a pointer to the typeglob (or in the case of ithread builds, an index into the pad which contains the typeglob). It's still slightly slower than lexicals since a few more pointers have to be followed.

      Dave.

Re: Examples of Where "our" is really needed
by Roy Johnson (Monsignor) on May 04, 2005 at 22:13 UTC
    What do you think our does, apart from placating strict? What do you think it does that use vars didn't?

    Caution: Contents may have been coded under pressure.
      From the camel book (3rd ed, p. 756):

      The primary use of an our declaration is to hide the variable from the effects of a use strict "vars" declaration; since the variable is masquerading as a my variable, you are permitted to use the declared global variable without qualifying it with its package. However, just like the my variable, this only works within the lexical scope of the our declaration. In this respect, it differs from use vars, which affects the entire package and is not lexically scoped.

      I am trying to think of some examples where this is a clear advantage. Either some tricks it makes work or ways it can be leveraged to make code cleaner. If all it was used for is declaring global variables then either declaring them up front with "my" or use vars would do. I figure there must be some higher reason for the "our" feature.

        You don't declare global variables, like you do my variables, or even local variables. You didn't declare them with use vars, and you don't declare them with our. Global variables spring into existence upon being used; they are not dependent upon mere mortals for their existence.

        The only thing that our buys you is the ability to refer to a global variable without its package specifier. If you can accomplish what you need to with lexical variables, you should use them. If you need globals, you may use them. If you use globals, you may use our to save typing the fully-qualified name every time you reference them. But that is all it buys you. our did not introduce any new kind of variable (nor did use vars).

        You could do it with use vars, but that (as the docs you quoted said) doesn't give you as tight of control over where the global can be referenced as a familiar. It is, according to its own docs, obsolete.


        Caution: Contents may have been coded under pressure.
Re: Examples fo Where "our" is really needed
by tlm (Prior) on May 05, 2005 at 00:15 UTC

    I doubt that you will find any example in which our makes a huge difference.

    So why bother having it at all? I suppose that the key idea behind our is to mitigate some of the dangers associated with global variables (when used in conjunction with strict). For instance, consider this case:

    use strict; use vars '$x'; $x = 3; sub critical { my $w = 50; # my $x = 100; # oops: commented out by mistake # my $y = 200; my $y = 300; frobnicate( $w, $x, $y ); # that's the global $x in there! }
    So, by a programming error the global value is now passing as a lexical. our offers a way to reduce the likelihood of such an error:
    use strict; $MyModule::x = 3; # ... sub critical { my $w = 50; # my $x = 100; # oops: commented out by mistake # my $y = 200; my $y = 300; frobnicate( $w, $x, $y ); # won't compile }
    ...but you can still turn off the qualification requirement selectively:
    sub that_uses_global_x_heavily { our $x; # we drop the formalities locally foobar( $x ); # ... $x = tweak( $x ); # ... and_one_more_thing( $x ); # ... }

    Of course, there are other ways to avoid the errors that this scheme is trying to prevent, starting with using very different naming conventions for globals and lexicals.

    So, bottom line, if you believe that (1) globals that are "easily accessible" (i.e. without the need for full qualification) from anywhere in the package are an invitation to difficult-to-detect bugs; and (2) fully qualified names are a pain, then our lets you have your cake and eat it too. Whether this capability was worth adding (along with the attendant confusion and pitfalls) would depend on how strongly you feel about (1) and (2).

    the lowliest monk

      Well, scope localization was not really the main issue, but a nice side benefit. The key point to our is that it is a single syntactic declaration for a single name, and as such, a location on which you can hang various extra modifiers controlling your view of that variable. That was envisioned from the start, though we're only just now getting there with Perl 5 "attributes" and Perl 6 "traits". In essence, the our declaration functions as a peg on which you can hang other declarations, which use vars could never do.
Re: Examples fo Where "our" is really needed
by adrianh (Chancellor) on May 05, 2005 at 11:03 UTC
    I seek some example to meditate upon in which the "our" syntax really helps improve the performance or readability of the code. Pray tell me what those examples might be!

    Two (small) advantages for me.

    First it allows me to type less and still have clarity. For example I prefer this

    our $VERSION = '1.00';

    to this

    use vars qw( $VERSION ); .... $VERSION = '1.00';

    or this

    $SomePackage::VERSION = '1.00';

    Secondly I like being able to localise access to scary things like globals to just where I need them so I can do things like this:

    sub AUTOLOAD { our $AUTOLOAD; .... };

    I admit these are small advantages, and some would say too small to drop backward compatability, but I like them and will quite happily continue to use our :-)

      I prefer

      $VERSION = '1.00';
      over any of your alternatives above. Now you might wonder how I handle strict. Fact is I don't. I don't have stricture enabled until I have done the assignment to $VERSION and other globals I don't plan to type again.

      being able to localise access to scary things like globals to just where I need them

      Just a clarification. I've seen people declare the same variable twice but one should not do

      sub foo { our $foo; ... } sub bar { ... } sub baz { our $foo; # BAD! ... }
      to avoid access to $foo inside &bar. Use some other scope trick for that if it's needed. One misses a great point of having the declaration if one does it more than once for the same variable.

      ihb

      See perltoc if you don't know which perldoc to read!

        The whole point of the word "our" in English is that it indicates shared property, and more than one person us allowed to say it about the same object without an argument breaking out. In Perl the word "our" does not declare a variable, but a private view of a public variable. It is quite properly limited to the lexical scope that uses the view. Sure, you can throw two functions into the one artificial lexical (or class) scope to share one "our" declaration, but that's a trick that doesn't scale well to multiply intersected sharings. Even Fortran got that one right.
        Fact is I don't. I don't have stricture enabled until I have done the assignment to $VERSION and other globals I don't plan to type again.

        Fair enough. I just can't be bothered to spend my limited brain power wondering about which globals I'll just use once, or bother spending time switching between methods if I change my mind later - so I just use our pretty much all of the time :-)

Re: Examples fo Where "our" is really needed
by polettix (Vicar) on May 05, 2005 at 12:38 UTC
    In one of my projects I have embedded a Perl interpreter into the main C++ application; I load (and eval) some external scripts at run-time and have no access to any module, even pragma ones (so no strict and vars). OTOH, I develop the scripts using strict, so I'm forced to declare all variables as lexically scoped.

    To add flexibility, I keep some configuration variables declared at the beginning of the main script, and leave the possibility to change these configurations including other configuration scripts later. This is where our came to rescue me: my fails miserably, restricting scope to each single eval I call.

    I know, it wasn't (probably) designed to solve my particular issue* - just a real world example, though...

    *To summarise, impossibility to use vars and multiple evals.

    Flavio (perl -e 'print(scalar(reverse("\nti.xittelop\@oivalf")))')

    Don't fool yourself.
Re: Examples fo Where "our" is really needed
by rg0now (Chaplain) on May 05, 2005 at 18:02 UTC
    Please, ignore this node, I wrote it before actually thinking. I am stupid...