Perl Part I · Module 12 · Modules and Packages
package and Namespaces
The previous chapter argued for one definition instead of two copies, and that argument has an obvious problem: if two reporting scripts both want a subroutine called parse_log, and both end up loaded into the same program, which one wins? A package is the answer. It gives every name declared after it a prefix, so VLSI::Timing::parse_log and VLSI::Power::parse_log are different names that can coexist in one process. Everything in this chapter happens inside a single file on purpose, because a package and a file are separate ideas that are almost always introduced together and then quietly confused — a file can hold several packages, and a package can span several files. The second half of the chapter is the part worth your attention. package reads like a scoping keyword, and it is not one: section four measures a variable declared inside a package block being alive and readable from outside after that block has closed.
Intermediate10 min readPerlPart IModules
Part I · Module 12 · Chapter 12.2 · package and Namespaces
1. Two Subroutines, One Name, No Collision
use strict;
use warnings;
# Two packages in one file, each with a sub of the SAME name.
package VLSI::Timing {
sub parse_log {
my ($line) = @_;
my ($pin, $slack) = $line =~ m{^(\S+)\s+(-?[\d.]+)$};
return "timing: pin=$pin slack=$slack";
}
}
package VLSI::Power {
sub parse_log {
my ($line) = @_;
my ($cell, $mw) = $line =~ m{^(\S+)\s+([\d.]+)mW$};
return "power: cell=$cell mw=$mw";
}
}
print VLSI::Timing::parse_log("u_alu/A -0.12"), "\n";
print VLSI::Power::parse_log("u_alu 3.4mW"), "\n";timing: pin=u_alu/A slack=-0.12
power: cell=u_alu mw=3.4Two subroutines called parse_log, both defined, both callable, in one program. That is the entire purpose of the construct.
The full name of a subroutine is its package name, then ::, then the subroutine name. Writing VLSI::Timing::parse_log(...) says exactly which one you mean, and there is no ambiguity for Perl to resolve.
Note that VLSI::Timing and VLSI::Power are not related to each other. The shared VLSI:: prefix is a convention for grouping names that belong to one project — it creates no inheritance, no shared data, and no requirement that a VLSI package exist at all. It is a naming scheme, nothing more.
2. Every File Starts in main
use strict;
use warnings;
# Every file starts in package main
printf "the default package is : %s\n", __PACKAGE__;
package VLSI::Log;
printf "after a package stmt : %s\n", __PACKAGE__;
package main;
printf "and back again : %s\n", __PACKAGE__;the default package is : main
after a package stmt : VLSI::Log
and back again : main__PACKAGE__ is how you ask which package you are currently compiling into, and it is the first thing to reach for when a fully-qualified name is not resolving the way you expect.
Every one of the hundreds of scripts in the previous eleven modules was in package main — which means every subroutine in them was really main::something. That was invisible because there was only ever one package, so no prefix was needed to disambiguate anything.
The statement form package VLSI::Log; switches packages for everything that follows, to the end of the file or until the next package statement. package main; switches back.
3. Block Form or Statement Form
use strict;
use warnings;
# The BLOCK form confines the package to the braces.
package Inner { our $where = "inside the block" }
printf "after the block form : %s\n", __PACKAGE__;
# The STATEMENT form runs to the end of the file or the next package statement.
printf "Inner::\$where : %s\n", $Inner::where;after the block form : main
Inner::$where : inside the blockAfter the block closes, __PACKAGE__ is main again — the block form confines which package subsequent code compiles into. That is what makes it the better choice when one file holds several packages, because the extent of each is visible from the braces rather than inferred by scanning forward for the next package statement.
The second line of output is the hinge of this chapter, and it leads straight into the next section: the variable declared inside that block is still readable from outside it.
4. A Package Is a Namespace, Not a Scope
This is the half of the canonical description that needs proving, because the syntax strongly suggests otherwise.
use strict;
use warnings;
# A package separates NAMES. It does not limit how long a variable lives.
package Counter {
our $calls = 0;
sub bump { $calls++; return $calls }
}
Counter::bump() for 1 .. 3;
printf "Counter::\$calls from outside : %d\n", $Counter::calls;
printf "still alive after the block : %s\n", (defined $Counter::calls ? "yes" : "no");
print "a package is a NAMESPACE, not a scope\n";Counter::$calls from outside : 3
still alive after the block : yes
a package is a NAMESPACE, not a scope$calls was declared with our inside a package block. The block has closed. The variable is still there, holds the accumulated count of 3, and is readable from outside as $Counter::calls.
A package block looks like a container and is not one. It changes the prefix applied to names declared inside it; it does not create a lifetime, and it does not restrict access. $Counter::calls is a global variable that happens to live under the Counter prefix, and anything anywhere in the program can read or write it.
So the two halves of the canonical description are both true and they are about different things. A package does separate names, reliably, which is section one. It does not limit how long anything lives or who can see it, which is this section.
5. Reaching Into a Package
Because package variables and subroutines are global names under a prefix, the full name works from anywhere.
use strict;
use warnings;
package VLSI::Units {
our $DEFAULT = "ns";
sub normalise { my ($v, $u) = @_; return $u eq "ps" ? $v / 1000 : $v }
}
# Reach a package variable and a sub with their full names
printf "default unit : %s\n", $VLSI::Units::DEFAULT;
printf "420 ps in ns : %s\n", VLSI::Units::normalise(420, "ps");
printf "0.42 ns in ns: %s\n", VLSI::Units::normalise(0.42, "ns");default unit : ns
420 ps in ns : 0.42
0.42 ns in ns: 0.42Note the shape of the variable's full name: the sigil comes first, then the package, then the variable — $VLSI::Units::DEFAULT, not VLSI::Units::$DEFAULT. That ordering catches people out, and the error it produces is unhelpful.
Calling a subroutine by its full name is always available and always unambiguous. It is also verbose, which is why use Module qw(name) exists to import a short name into your own package — the mechanism is Chapter 12.6's, and use itself is the next chapter.
One caution worth stating here. Because these names are global, use strict does not protect you from a typo in a fully-qualified name the way it does for a my variable. $VLSI::Units::DEFALT is a perfectly legal name for a global that nobody has set, so it reads as undef and, under use warnings, produces an uninitialised-value warning rather than an error. Chapter 12.7 returns to this.
6. What To Remember
- A package gives every name after it a prefix, so two
parse_logsubroutines can coexist in one program. - The full name is
Package::subfor a subroutine and$Package::varfor a variable — sigil first. - Every file starts in
main. Every script in the previous eleven modules was really definingmain::subroutines. - The statement form runs to the next
packageor the end of the file; the block form is confined to its braces. Prefer the block form when one file holds several packages. - A package is a namespace, not a scope. Measured: an
ourvariable declared inside apackageblock is alive after the block and readable from outside as$Counter::calls. - So
ourin a module publishes that variable. Any caller can change it;myat file scope is the private alternative, and Chapter 12.7 measures the difference. - A shared prefix implies nothing.
VLSI::TimingandVLSI::Powerare unrelated, andVLSIneed not exist. use strictdoes not catch a typo in a fully-qualified name, because that name is a legal global.- A package and a file are different things. One file can hold several packages; this whole chapter is one file.
Chapter 12.3 moves from declaring a package to loading one from another file, and the two ways to do it. use loads at compile time and imports names; require loads when the line runs and imports nothing — and the measurement there shows the difference in the starkest possible form, where one version prints nothing at all.
Where this fits
Part of the Perl curriculum.
