Parham has asked for the wisdom of the Perl Monks concerning the following question:
and i have this vague notion that a variable can be global if i do this:use strict; our $var = 22; #global var (or so i think)
so here's my question. Is there a way to let a variable be a variable (just $variable) without the use of 'our' and still have a clean program without warnings? Just curious, and a bit confused. I couldn't find a full explanation anywhere on perlmonks and i did do a whole lot of searches.$global::variable = 'global'; #global variable print $global::variable; #but it looks ugly
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
(Ovid) Re: declare globally
by Ovid (Cardinal) on Jan 09, 2002 at 06:07 UTC | |
There are basically four ways of declaring a global variable (well, I could some up with some others using soft references, but they're bad juju).
1: $global::variable;
2: no strict 'vars';
$variable;
3: our $variable;
4: use vars qw/$variable/;
Of the three, the first should not be encouraged as it's easy to misspell the global and strict won't tell you that. This makes your program more likely to be buggy. The second is terrible because you lose all benefits of strict, even with lexically scoped variables (misspelling the lexically scoped variable means Perl will think it's a global). The third is new, as of Perl 5.6. It allows you to declare a lexically scoped global variable. If that sounds confusing, good. If you lexically scope your globals, it can become confusing if you use the same name outside of the scope because then it's easy to misunderstand whether or not something is global. The "use vars" pragma is the cleanest, IMHO. You can declare it as global, it's not lexically scoped, and when you run across it later in your program, you know it's a global, no questions asked. All of the above information aside, using global variables can be very dangerous because they are more difficult to manage. As a side note, the first method is the only one (of the four that I present) that allows you to declare a global in another package. That's might be acceptable if you're exporting a global that a person asks for in their program, but it's usually bad programming to mess with someone else's namespace. Cheers, Join the Perlmonks Setiathome Group or just click on the the link and check out our stats. | [reply] |
|
Re: declare globally
by VSarkiss (Monsignor) on Jan 09, 2002 at 05:16 UTC | |
The document you want isn't at the Monastery, though it was written by our own Dominus. It's called Coping with Scoping. The short answer to the question I think you're asking is to use vars qw($var). HTH | [reply] [d/l] |
|
Globals, localisation and strict.
by jarich (Curate) on Jan 09, 2002 at 06:14 UTC | |
will generate compile time errors because we haven't told Perl about the scope of the $global variable. Now there are several ways we can declare variables in Perl, and of course they mean different things. use vars, and our give globals: These can then be used anywhere in their package as you'd expect of globals. They can also be accessed outside of the package by fully qualifying them. eg fully qualifying variables gives globals. Kinda like the above, and your example. In your code you're created a new namespace (global) and using that for your globals. Yes, it is ugly, but it's perfectly valid. my localizes variables to their block. local temporarily displaces the value of a variable until the end of the block Be careful of declaring a local variable of the same name as a another variable previously declared with my in the same scope. It should complain, and it does. That is:
The difference between my and local is a subtle one. Local variables exist for that call stack, until the end of the block. So if your block calls subroutines, the localised variable will exist within those subroutines (and any subroutines they call and any they call and so on - which can cause nasty surprises). Variables declared with my exist _only_ within their block. This means that if the block calls a subroutine that is not defined within the same block, then that subroutine does not automatically get access to the variable (but you can pass it in as an argument). Excepting these, you cannot access variables declared within a block, at all, from outside that block. That is: will result in a compile time error. Phew! I hope that helps. Jacinta. | [reply] [d/l] [select] |
by Juerd (Abbot) on Jan 09, 2002 at 06:21 UTC | |
I think having a package called Main is pure evil. I hope the capital M was a typo :)
| [reply] [d/l] |
|
Re: declare globally
by danger (Priest) on Jan 09, 2002 at 05:33 UTC | |
| [reply] | |
|
Re: declare globally
by CharlesClarkson (Curate) on Jan 09, 2002 at 13:06 UTC | |
Many times I find that what people call global is just a file scoped variable. In this case a lexical or constant works fine. I think the biggest mistake made with global variables is not finding out what global means to the questioner. How do you define "global"? Why do you want to use a global variable? Is this variable to be read-only? Are you passing the variable amongst modules or scripts or just in this one script? HTH, Charles K. Clarkson | [reply] |
by Parham (Friar) on Jan 09, 2002 at 16:29 UTC | |
Even with perl's implementation of 'our' as an internal function, will it still be wiser to use 'use' instead of 'our'? | [reply] |
by dmmiller2k (Chaplain) on Jan 09, 2002 at 21:12 UTC | |
You really should read the article at this node: 'our' is not 'my', if you haven't already. It specifically addresses your question about whether (or when) to use use or our. What it perhaps fails to address is the fundamental difference between lexical variables (declared with 'my') and package globals. Originally, before there were such a thing as lexical variables, ALL variables were [package] globals. Global variables involve underlying constructs called typeglobs, which are basically symbol table elements. One typeglob is created for each unique symbol name in a package, and is shared among various objects with the same name (but different types). Therefore a package global, $foo shares its typeglob with the package global, @foo, and with the package global, %foo, and with the file handle, foo, ... you get the idea. There is an entire body of literature describing this, probably far better than I ever could, so I won't go into further detail here (try using Super Search), except to say that a given typeglob contains what may be thought of as "slots" for each kind of thing (variable or handle) that Perl can support. There is a scalar slot, array slot, hash slot, file handle slot, code slot, etc. For at least scalars, arrays and hashes, the value that goes into the slot is a reference to the appropriate type (or nothing, i.e., undef). So when you take a reference of a package global, using the notation, say, \@arr, what you are doing is simply extracting whatever is in the array slot of the typeglob named 'arr'. The entire typeglob may, itself, be referred to as *arr, should you ever want to do this. Legacy code (i.e., perl4) may contain some typeglob manipulation, since that was pretty much the only way to do several things, such as passing around filehandles. Which (finally) brings me to lexicals. These have two fundamental differences from package globals. First, they are actually created on the stack (and therefore are destroyed when they go out of scope), and second, they do NOT use typeglobs (which has more subtle implications). As such, same-named lexical variables of different types do not share symbol table space. They also cannot be manipulated with the typeglob notation (*variable), but they have the distinct advantage of being destroyed upon going out of scope. Some of the power of Perl (such as aliasing variables and whatnot) cannot be used with lexicals. For example, if $main::foo contained the value, 'hello' and if you set \*main::bar = \*main::foo, then $main::bar would thereafter be an alias, indeed another name, for the scalar value referred to by $main::foo (similar to the concept of "hard links" on UNIX filesystems). Changing the value of $main::foo changes the value of $main::foo and vice versa. So, if you are struggling with the answer to the question, "Should I use a file-scoped lexical or a global?" perhaps understanding the underlying difference between the two may help, somewhat. dmm You can give a man a fish and feed him for a day ...Or, you can teach him to fish and feed him for a lifetime | [reply] [d/l] [select] |