Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

declare globally

by Parham (Friar)
on Jan 09, 2002 at 05:06 UTC ( [id://137331]=perlquestion: print w/replies, xml ) Need Help??

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

now i've looked and looked and i still don't FULLY understand how to declare a variable globally (all the different ways)

I know that i can use strict and declare variables globally using 'our'.. ie:
use strict; our $var = 22; #global var (or so i think)
and i have this vague notion that a variable can be global if i do this:
$global::variable = 'global'; #global variable print $global::variable; #but it looks ugly
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.

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,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

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

Globals, localisation and strict.
by jarich (Curate) on Jan 09, 2002 at 06:14 UTC
    use strict forces you to provide scoping information about your variables. Hence:
    use strict; $global = 1;
    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:

    # globals to our package. use vars qw/$global1 $global2 $fred/; our ($global1, $global2, $fred);
    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
    use strict; package Fred; our $name = "John"; package Main; my $name = "Fred"; print $Fred::name; # prints "John"; print $name; # prints "Fred";
    fully qualifying variables gives globals.
    Kinda like the above, and your example.
    use strict; $::database = "backup"; # global variable in Main # package. package Fred; print $::database; # prints "backup";
    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.

    #!/usr/local/bin/perl -w use strict; my $fred = 3; # accessible from here to end # of file/package. { my $fred = 2; # overrides previous $fred until # end of block print $fred; # prints "2"; } print $fred; # prints "3"
    local temporarily displaces the value of a variable until the end of the block
    use strict; my @array = qw/this is a sentence/; { local $, = " "; # changes $, to " ". Using # "my" with a Perl special # variable generates a compile # time error. print @array; # prints "this is a sentence" } print @array; # prints "thisisasentence"
    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:
    use strict; my $foo = "bar"; local $foo = 2; # will break. # although { local $foo = 2; # will be fine. }

    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:

    use strict; package Foo; my $foo = 12; package Bar; print $Foo::foo; # this won't work
    will result in a compile time error.

    Phew! I hope that helps.

    Jacinta.

      (Just a side note)
      I think having a package called Main is pure evil. I hope the capital M was a typo :)

      2;0 juerd@ouranos:~$ perl -e'undef christmas' Segmentation fault 2;139 juerd@ouranos:~$

Re: declare globally
by danger (Priest) on Jan 09, 2002 at 05:33 UTC

    The following two nodes (and their ensuing threads) may help clarify certain aspects of the differences between my(), our(), local(), and 'use vars': here and here

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
      all of your answers were very well put :). The reason for the question (and it is valid in my point of view) is that i have variables being passed through several scripts and subroutines and instead of continuously passing them around and around, i just wanna keep them global. I'm not worried about losing track of my global variables, because i know all of my global variables start with $global_(variablenameinhere) and i do keep all my variables named accordingly with prefixes of what they do or what they're there for.

      Even with perl's implementation of 'our' as an internal function, will it still be wiser to use 'use' instead of 'our'?

        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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://137331]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (6)
As of 2024-03-28 14:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found