in reply to About packages and scopes

Under strict, global variables must contain the package name, eg:
# CGI post max $CGI::POST_MAX = 4096; # if you are using strict, the global # variable age in your 'main' script # would need to be like this $main::age = 31; # or (same) with implicit namespace of 'main' $::age = 31;
If the package correctly exports variables/subs, they will be available in the namespace you are in. In the case of the CGI module, you can choose which elements are exported, eg
use CGI qw/:standard/; print header(), start_html(), h3('hello'), end_html();
Take a look at the module for examples of other possible values.

Using 'my' to declare variables is best practice where possible. If you really do need truely global vars, then define by prepending "namespace::".

If you are not using strict, just defining a variable implies that the variable is global, ie:

# no strict, so.. $age = 31 # is the same as these (in the 'main' script): $::age = 31 $main::age = 31

If you look, you will see that CGI.pm is NOT using 'strict', so it can define global variables such as $POST_MAX that are global, without having to explicitly using the package name.

But because these are global, you can access them from other packages through the namespace, eg:

$CGI::NPH=1

Still not very clear, is it? :) Why not create some play packages to experiment until this all sinks in?

Just my morning .02

cLive ;-)

Update: - please read tilly's comments below as well for info on stuff I didn't know about (our & vars - I still use Camel V2...). Also, added 'of main' to 'implicit namespace in code to avoid (possible) confusion. (All I meant was that $main:: and $:: are equivalent, with the main being implied in the $:: case. Not as Tilly thought, that $:: implies the current package.

Replies are listed 'Best First'.
Re (tilly) 2: About packages and scopes
by tilly (Archbishop) on Nov 20, 2001 at 01:08 UTC
    Some mistakes and corrections.

    First of all with strict on you can declare global variables with vars or (in 5.6) with our. (I prefer vars.) Then you don't have to use fully qualified names. In fact doing this is both customary and preferred, because it extends strict's typo checking to global variables, and makes it easier to change what package code is written for. (I would, in fact, assume that anyone routinely using fully qualified names instead of declaring them is simply unaware of how to declare them. Furthermore I would strongly suggest rewriting code which uses lots of fully qualified names without very specific cause.)

    Secondly and more importantly, your comment about "implicit namespace" on the $::foo construct is likely to mislead, and may indicate confusion on your part. Writing $::foo does not declare a global in your current package. Instead it declares a global in package main.

    How does this work? Well it is simple. Your root namespace is main. In main there is a package main:: which is a reference to the root namespace again. Therefore $::foo is the same as $main::foo is the same as $main::main::foo, etc. (Likewise $foo::bar is the same as $main::foo::bar.) So $::foo is a fully qualified name of a global variable in package main, not your current package.

    Therefore there is nothing really implicit about $::foo. And nobody should let the word "implicit" fool you into thinking that it is in the current package. It is in package main.

    UPDATE
    Added a closing bracket. danger caught the typo.

Re: Re: About packages and scopes
by nlafferty (Scribe) on Nov 19, 2001 at 22:18 UTC
    Short and sweet. Thanks, it did help. I will try a few things and see what happens