in reply to overview/tutorial on packages - creation and use

Packages provide namespaces for non-lexical variables (those declared with our or with a fully qualified name). Within any given namespace there may be only one variable (of each datatype) with a given name. Using namespaces is kind of like if you have several friends with the same first name (their last name provides different "packages" for each). Likewise in order to disambiguate when the context is not clear which one you're referring to you name them by their full name which includes the namespace (first and last).

## Since we use strict we have to declare the names of our package ## variables with our use strict; package Smith; our $John = 1; package Jones; our $John = 2; # prints 2, because package Jones is the current package; print $John, "\n"; # prints 1 because we explicitly name the other package's var print $Smith::John, "\n"; package main; print $John, "\n"; # Compile time error because there's no $main::Joh +n

Now as for your question, your hash might presumably be called %names. What if you're writing code which maps constellations to the names of astronomers who discovered some feature therein and you want to call that hash %names as well (and yes, this is against PBP variable naming advice; indulge my hypothetical :).

You could put the constellation names hash in a package Constellations, while the other goes in Astronomers. Then your code would use $Constellations::names{ "Big Dipper" } or keys %Astronomers::names or what not to access them. You also could use Exporter to import the variables into other package's namespaces and refer to them with an unqualified %names instead to save yourself some typing.

Replies are listed 'Best First'.
Re^2: overview/tutorial on packages - creation and use
by shmem (Chancellor) on Apr 21, 2007 at 20:11 UTC
    (those declared with our or with a fully qualified name)

    According to the docs, variable symbols declared with our are lexical symbols (although the symbol table entry they refer to is a package global):

    our associates a simple name with a package variable in the current package for use within the current scope. When use strict 'vars' is in effect, our lets you use declared global variables without qualifying them with package names, within the lexical scope of the our declaration. In this way our differs from use vars , which is package scoped.

    What makes them look like non-lexicals is their auto-vivification of package globals.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re^2: overview/tutorial on packages - creation and use
by chexmix (Hermit) on Apr 21, 2007 at 18:55 UTC
    Thank you! The emphasis on disambiguation has helped clarify the topic of namespaces for me.

    Partly, I guess, because I am not terribly far along in my learning, I had gotten the idea that a "package" was necessarily a completely separate file of stuff - that could then somehow be imported (and that a Module was "simply" a specific kind of package) and then accessed/used/referenced. I see now that among other things, it is more subtle than that.

      I had gotten the idea that a "package" was necessarily a completely separate file of stuff - that could then somehow be imported (and that a Module was "simply" a specific kind of package) and then accessed/used/referenced.
      You've got that impression because thats the standard way it's used :-) It normally makes not much real sense to put multiple packages in a single script file. Imagine you write a script where you put your package Astronomers; with a longish hash and package Constellations; with a longish hash and your code below in main. The other day you need both packages again for a second script. Then you copy and paste both packages into your new script file....an excellent source for bugs.

      Regarding the "longish hash" itself. It's a design flaw to have modules/packages that do nothing than containing data. It's better to save your data where it belongs, in a file or a database, and let you're code read it. That way it's far easier to copy with changes in your data.


      holli, /regexed monk/