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

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

This is, in many ways, a followup to chipmunk's excellent post, but with a slight twist in that I do not consider our() or 'use vars' as ways of declaring global variables (there is a subtle but important distinction to be made). OzzyOsbourne asks:

1.Is there any difference between declaring variables at the beginning of scripts with my or our? Won't their scope be the same?

Yes, there is a difference, and the difference is that No, the scopes of the *variables* will not be the same --- one will be a lexical variable (my) and the other will be a package-global variable (our). I think one major problem people have with my(), our(), and 'use vars' is that we all tend to discuss them as ways of declaring 'variables', and then confusion sets in because the scope of what we declared doesn't always coincide with the scope of the variable which doesn't seem to make sense. Do not think of our() and 'use vars' as ways of declaring *variables* and things become clearer.

Lexical variables *are* declared and created with the my() declaration. Package variables are never really "declared" at all ... what is really being declared with either 'use vars' or our() is not the variable per se, but "unqualified access" to a package variable under the 'strict' pragma.

  • my creates a lexical variable that only exists and is only accessible within its immediate enclosing lexical scope. It is not accessible anywhere else and does not exist in the package symbol table (so trying to qualify a lexical variable name with a package name will *not* get you the lexical variable).
  • package globals are always accessible from anywhere using their fully qualified package names. Package variables never need to be declared. However, package variables must be qualified with their package names when 'use strict' is in effect except under the following situations:
  • our declares 'unqualified access' to a package variable such that unqualified access is only allowed within the immediate enclosing lexical scope of the declaration (even if that lexical scope crosses package boundaries). It is the scope of unqualified access that is lexical, not the variable.
  • use vars declares unqualified access to a package variable such that unqualified access is granted anywhere within the package to which it belongs (even if that package scope crosses a lexical boundary such as a file boundary).

So, can there be any *effective* difference between declaring a variable with our() or my() at the top of a single, single self contained script? Well, although it certainly isn't good programming style to reuse the same variable names, one difference is that you can never fully mask out a package variable:

#!/usr/bin/perl -w use strict; my $foo = 42; our $bar = 21; print "$foo, $bar, $main::bar\n"; { print "$foo, $bar, $main::bar\n"; my $foo = 7; my $bar = 9; print "$foo, $bar, $main::bar\n"; }

Inside the inner block a new lexical $foo is created completely masking out access to the outer lexical $foo (for the remainder of the inner block). A new lexical $bar is also created but only masks *unqualified* access to the package variable $bar, the package $bar is still (is always) accessible via its package name. But that is a contrived example.

Is it better to use my() or our() in single scripts? That is a matter of style and opinion. My rule is to only use package variables when a package variable is necessary. Thus the question isn't "should I use my() or our()?" ... that answer is dictated by whether I need a package variable or not, and then, if I *do* need a package variable, the question really is :should I use our() or 'use vars'?". I guess that depends, but sometimes our() variables won't cut it because their unqualified access is lexically scoped rather than package scoped. For example, if you use the Getopt::Declare module and wish to include a variable within an action-block the docs state that:

Actions are executed (as `do' blocks) in the package in which the Getopt::Declare object containing them was created. Hence they have access to all variables and functions in that scope. (ed. emphasis added)

This is accomplished inside the Getopt::Declare module by taking the action block (as a string), wrapping it in a do block with the caller's package declaration added and eval()'ing it. This means that if the action uses unqualified access to a package global it must be declared with 'use vars' and not our() because the unqualified access of our() is lexically scoped and won't be in effect inside Getopt::Declare's evaluation of the code. For a concrete example:

#!/usr/bin/perl -w use strict; use Getopt::Declare; # use vars '$foo'; # this will work our $foo; # this won't work $foo = "Hello World\n"; my $spec = <<'EOS'; -greet print a greeting {print $foo} EOS my $opts = Getopt::Declare->new($spec); __END__

The above (using our()) will generate an error, but if you use the commented out 'use vars' declaration instead, it will work fine. (aside note: the '-greet' above is followed by a hard tab, not spaces).

My first hard and fast rule is that there are no hard and fast rules. My second hard and fast rule (subject to qualification via the first rule) is to always use lexical variables except when a package variable is required and then 'use vars' is generally still my first choice. In the few instances where I want a package variable, I do not see that our() gives me any additional benefits over 'use vars', and occassionally (as in the Getopt::Declare situation) our() doesn't satisfy the access needs.

In reply to Re: Re: Re: Our, use vars, and magic, oh my! by danger
in thread Our, use vars, and magic, oh my! by OzzyOsbourne

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?

What's my password?
Create A New User
Domain Nodelet?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (4)
As of 2023-11-30 03:38 GMT
Find Nodes?
    Voting Booth?

    No recent polls found