Life is a struggle with things to maintain itself among them. Concepts are the strategic plan we form in answer to the attack.
One of the chief reasons why languages such as awk and the various Unix shells don’t get used for building even moderately complex systems is their lack of support for modular programming. There are no bodies of code that you can just pick up and plug into your application; instead, you end up cutting and pasting from other standalone scripts. In contrast, languages such as Perl have been highly successful because of the wide availability of third-party modules (libraries). When comparing languages, I consider the availability of libraries to be more important than pure language features.
Perl allows you to partition your code into one or more reusable modules. In this chapter, we will study how to:
Define modules using the package
keyword.
Load predefined modules with use
and
require
; we have already seen a few examples of
use
in the earlier chapters.
Access package specific variables and subroutines using the “::” notation.
Load functions at run-time.
The package
keyword signifies the beginning of a new namespace. All global
identifiers (names of variables, subroutines, filehandles, formats,
and directory handles) mentioned after this statement
“belong” to that package. For example:
package BankAccount;
$total = 0;
sub deposit {
my ($amount)= @_;
$total += $amount;
print "You now have $total dollars
";
}
sub withdraw {
my ($amount)= @_;
$total -= $amount;
$total = 0 if $total < 0;
print "You now have $total dollars
";
}
The user-defined global identifiers $total
,
deposit
, and withdraw
belong to
the BankAccount package. The scope of a package lasts until the end
of the innermost enclosing block (if it is declared inside that
block) or until another package
statement is
encountered. In the absence of an explicit package declaration, Perl
assumes a package name called main
.
This is how you use the global symbols from another package:
package ATM; # Start a different name-space now BankAccount::deposit(10); # Call a foreign subroutine print $BankAccount::total; # Access a foreign variable
To access an identifier in a different
namespace, you
need to put the package name before the variable name; this is called
fully qualifying the name. Note that you must
say $BankAccount::total
, not
BankAccount::$total
; the $
sign
is followed by the fully qualified name. If an identifier is not
fully qualified, Perl looks for it in the currently active package.
Since the package
statement simply dictates the
effective namespace, you can switch between different namespaces at
will:
package A; $a = 10; # This $a is in package A package B; $a = 20; # This $a is in package B, and is completely independent # of the other $a package A; # Make A the current package. print $a; # prints 10;
C++ programmers will recognize the resemblance to that language’s namespace facility.
In Chapter 3, I mentioned that all global names go
into a symbol table. That was a bit of a white lie. Each package
actually gets its own
symbol table, distinct from all others.
(We will have more to say on this subject in Section 6.8 later in this chapter). User-defined
identifiers in package main
are not treated
specially in any way except that you can also refer to a variable,
say $x
, in that package as
"$::x"
.
The built-in variables such as $|
,
$_
, @ARGV
, and
%ENV
always belong to package
main
, and Perl allows you to refer to these
variables in any package without having to prefix them with
main::
. These are the only truly global variables
in Perl.
You may also recall that
lexical
(my
) variables are not associated with symbols and
typeglobs and therefore have nothing to do with packages. It is a
compile-time error to say something like
my $BankAccount::total; # Error
This also means that you can have two variables of the same type and the same name, if one is a package global and one is a lexical. The following piece of code is legal, but definitely not recommended:
$x = 10 ; # global to package main my $x = 20; # lexical at file scope print $x; # prints 20. Lexical variables are given priority.
Symbolic references work as we have seen earlier, for variables as well as functions. Consider
package A; $x = 10; package B; # Access $A::x symbolically print ${"A::x"}; # or even more indirectly $pkg = "A"; $var_name = "x"; print ${"${pkg}::$var_name"}; # Call a subroutine indirectly &{"A::foo"}(10, 20); # Identical to A::foo(10,20);
We will make extensive use of this facility in Chapter 8.