OzzyOsbourne has asked for the wisdom of the Perl Monks concerning the following question:
I looked at the docs, looked at some threads, delved into the CB, and consulted the magic 8 ball, but I still can't seem to get my head around the answer to:
What is the difference between my, use vars, and our?
Most answers seemed vague, or I just didn't understand. The most worrysome answer was "Outlook not so good" from the magic 8-ball. I'm an NT admin. I know about Outlook not so good. Tell me about Perl scope, 8-ball. Perl scope!
What I think I know:
- my declares variables in lexical scope. Yup, got it.
- use vars allows you to declare global variables, and refer to $package::$foo as $foo. Right on.
- and our is the same as use vars but with lexical scope. A globally lexically thingy. OK.
So on line 4 or 5, before any blocks, I declare my $foo. It acts with a lexical scope of the entire script. It acts sort of like a global variable.
What if I put our $foo in the same place. Do I get the same effect? What if I put use vars $foo?
My questions:
- Is there any difference between declaring variables at the beginning of scripts with my or our? Won't their scope be the same?
- Is there a reason to use one or the other in this situation
See this example. Look at %TOC. Should it be my or our?
Thanks for your help.
-OzzyOsbourne
Re: Our, use vars, and magic, oh my!
by dragonchild (Archbishop) on Aug 23, 2001 at 17:34 UTC
|
In a one-file script, there is no difference between my, our, and use vars, when declaring a variable outside any given block.
However, the difference comes in when working with functions or multi-file applications.
- my says that this variable cannot be used outside its scope. When this scope goes away, this variable is killed.
- our says that this variable cannot be used outside its scope. When this scope goes away, this variable stays around.
- use vars says that this variable gets to ignore strict. It has no scope (other than the whole program).
A good code example would be the following:
sub foo {
my $x;
$x++;
return $x;
}
print foo() for (0 .. 10);
Try that, then change my to our. You'll see what I mean.
------ /me wants to be the brightest bulb in the chandelier!
Vote paco for President! | [reply] [d/l] |
Re: Our, use vars, and magic, oh my!
by chipmunk (Parson) on Aug 23, 2001 at 21:20 UTC
|
There are basically two kinds of variables in Perl.
- Package variables live in the symbol table, and are accessible from anywhere in the program. (In some cases the access requires using a package qualifier.)
- Lexical variables do not live in the symbol table, and are accessible only from within the lexical scope where they are declared.
However, there are three ways to declare a variable (in the latest version of Perl).
- use vars qw/ $var /; declares $var as a variable in the current package. Within that package, you can write $var to get that variable. From anywhere, you can write $Pkg::var.
- my $var; declares $var as a variable in the current lexical scope. Within that scope, you can write $var to get that variable. That's the only way you can access it, and the only place in the code you can access it.
- our $var; declares $var as a variable in the current package, and sets up $var as an alias to that variable within the current lexical scope. Within that scope, you can write $var to get that variable. From anywhere, you can write $Pkg::var.
Of course, this will be much easier to understand with some examples.
| [reply] [d/l] [select] |
|
An excellent explanation, but if you look at the example that I provided, what is the answer to question 1? The only post that seems to answer the question is dga's. Is my and our the same in my example?
-OzzyOsbourne
| [reply] [d/l] [select] |
|
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.
| [reply] [d/l] [select] |
|
You seem to be looking for an answer that says, "You absolutely should use my..." or "You absolutely should use our..." to declare variables at the top of the script. Well, there really isn't a definite answer like that. It partly depends on how you're using the variables, and partly on personal preference.
If you are only using the variables from within that file, then you can declare with my. But you can still declare with use vars or our as well. It's really up to you. The script you're asking about should work the same whichever way you declare %TOC.
If you are accessing the variables from another file, then you have to declare with use vars or our. They are mostly the same when used at the top of the file, but our has the unusual behavior of crossing package boundaries.
Personally, I still do most of my coding for perl5.005, so I don't use our. I generally use my, except when I'm declaring packing variables or working with mod_perl.
| [reply] |
Re: Our, use vars, and magic, oh my!
by mandog (Curate) on Aug 23, 2001 at 17:10 UTC
|
| [reply] |
|
| [reply] |
Re: Our, use vars, and magic, oh my!
by arhuman (Vicar) on Aug 23, 2001 at 17:58 UTC
|
The only thing that bothers me is that we have at the same time :
- 'use vars' and 'our' are equivalent in the sense that they make a variable reachable from outside of the package.
- 'our' make a variable lexically scoped.
I have no problem with the first point (I've checked it several times).
But I thought that lexically scoped vars couldn't be accessed from the outside
beccause they weren't in the package's namespace (but were in a 'scratchpad').
Did I wrongly assume that 'lexically scoped' implied the use of a 'scratchpad'
(was it rather 'my var' implies use of scratchpad)
or does it mean that despite being lexically scoped a 'our' variable is also 'exported' in the namespace ?
Anyone to clear this point ?
"Only Bad Coders Code Badly In Perl" (OBC2BIP)
| [reply] |
|
The fact that a variable is lexically scoped doesn't imply anything about the internal implementation. Lexical scoping is more a matter of syntax than anything else.
According to the man page perlfunc:our or perldoc -f our, you can see that what the package Foo; our $foo; declaration does is get the interpreter to see occurrences of $foo unadorned, as it were, as occurrences of $Foo::foo, so it's a plain ol' package global:
An "our" declaration declares a global variable
that will be visible across its entire lexical
scope, even across package boundaries. The
package in which the variable is entered is
determined at the point of the declaration, not at
the point of use.
HTH
perl -e 'print "How sweet does a rose smell? "; chomp ($n = <STDIN>);
+$rose = "smells sweet to degree $n"; *other_name = *rose; print "$oth
+er_name\n"'
| [reply] [d/l] [select] |
Re: Our, use vars, and magic, oh my!
by dga (Hermit) on Aug 23, 2001 at 19:32 UTC
|
Update: can't believe I missed an important point. This is only if these are declared in a seperate block. D'oh.
my $x;
if($test)
{
my $z;
func();
}
sub func
{
#cant see $z
#can see $x since the sub is in the same scope as $x
}
Mea Culpa.
1.Is there any difference between declaring variables at the beginning of scripts with my or our? Won't their
scope be the same?
2.Is there a reason to use one or the other in this situation
1. The scope is the same. our variables cannot be used outside the current file (unless they are declared in the other file of course).
In the file there is an important difference though. our variables can be seen in subroutines and my variables declared at the top of your script cannot be seen inside your subroutines. You must pass them in.
2. If you don't want your subs to see the variables without being passed in ( ie as global ) then you should use my.
| [reply] [d/l] |
|
use strict;
my $var = 4;
sub foo {
$var = 'bar';
}
foo;
print $var;
-- Hofmator
| [reply] [d/l] |
|
|