5.1 Packages
A package allows us to define what is called a namespace. A package defines a unit of code within which the variable and function names used are safe from being overridden by other units of code that may use the same variable and function names.
In Perl, like any programming language, names of variables and functions are stored in an internal table called the symbol table. When we do not declare packages on our own, all names are stored in the symbol table for a package called main. However, when we partition our code into packages, each package has its own symbol table. As a result, the same name can be used in two or more packages without any confusion if we qualify the name of the variables with its home package’s name.
The program given below is very simple. We have broken it up into packages only for the purpose of illustration. Usually packages are not needed if the program is small in size.
Program 5.1
#!/usr/bin/perl
package Sean;
$firstname = "Sean"; $hometown = "Montreal";
$height = 67; $weight = 140;
$age = 21; $year_met = 1995;
#---------
package Tommy;
$firstname = "Tommy"; $hometown = "Washington DC";
$height = 66; $weight = 140;
$age = 18; $year_met = 1997;
#--------
package main;
$firstname = "Chad"; $hometown = "San Francisco";
$height = 73; $weight = 180;
$age = 23; $year_met = 1995;
printf "%s\t%s\t%s\t%s\t%s\t%s\n", $firstname, $main::hometown, $height,
$weight,
$age, $year_met;
printf "%s\t%s\t%s\t%s\t%s\t%s\n", $Tommy::firstname, $Tommy::hometown,
$Tommy::height, $Tommy::weight, $Tommy::age, $Tommy::year_met;
printf "%s\t%s\t%s\t%s\t%s\t%s\n", $Sean::firstname, $Sean::hometown,
$Sean::height, $Sean::weight, $Sean::age, $Sean::year_met;
The beginning of a package with the name package_name is signaled by the declaration
package package_name
The scope of a package declaration starts immediately after the package statement and continues either till the end of the innermost block that contains the statement or till another package statement is encountered.
In the program given above, there are three packages. The first package is called Sean, the second package is called Tommy and the last package is called main. The Sean package starts from the
package Sean;
statement and continues till we encounter the
package Tommy;
statement. In package Sean, we assign values to a set of scalar variables.
The next package is called Tommy and in this package, we assign values to the same set of scalars as we did in the Sean package. But, the two sets of variables are in two packages and therefore the earlier values do not get overridden. The two sets of names are in two namespaces and therefore remain unviolated by one another.
Finally, we have a package called main. The main package is default and if there is no confusion regarding where it begins, the
package main;
declaration is not needed. However, in this case, without this statement, we would not know where the Tommy package ends and the main package begins. In the main package also, we have assigned values to exactly the same set of variables as we did in the previous two packages. But, once again, since the three sets of names are in three different namespaces or symbol tables, they do not disturb one another and coexist in harmony within their own fenced spaces.
The main package is the default package. So, to refer to variables which reside in the main package we can simply write the variable name as we have done earlier. However, it is also possible to qualify the name of a variable in the main package using the name of the package, i.e., the symbol main. So, $main::hometown and $hometown refer to the same variable in the main package. When we use the name of a package as a qualifier, the $ sign that tells us that a variable is a scalar must be placed before the name of the package. In other words, we need to write the $ sign, then the name of the package without any intervening space, then two colons ::, and finally the name of the variable without the $ sign.
In the main package, to refer to the name of a variable in a package that is not main, we must qualify the name of the variable by the package’s name. Therefore, in main, we refer to the $firstname variable in the Sean package as $Sean::firstname and we refer to the $firstname variable in the
Tommy package as $Tommy::firstname.
The program given above prints the values of the $firstname, $hometown, $height, $weight, $age and $year_met variables from the three packages: main, Tommy and Chad.
The output of the program is given below.
Chad San Francisco 73 180 23 1995 Tommy Washington DC 66 140 18 1997 Sean Montreal 67 140 21 1995
In this example, a package contains only simple scalar variables. If a package contains list or hash variables or functions, their names must also be qualified outside the home package, i.e., outside the package in which they are defined. For a list variable, the @ sign must precede the name of the package, and for a hash variable the % sign must precede the name of the package. Outside the home package, if we place the & symbol before the name of a subroutine, we must place it before the name of the home package. In addition, a filehandle in another namespace can be used in the currently extant package by using the package modifier in front.
This example shows that several packages can reside in the same physical file. Usually, it is a good habit to write one package in one file, but it is not necessary. When we have several packages in one file, it is possible to go back and forth among the packages. To enter a package we use the package declaration with the name of the package whose namespace we want to use. There is no explicit way to leave a package. We leave a package when another package starts or the program ends. The package declaration can be used inside explicit blocks created using braces. Once a package
starts in a program, all unqualified names are in the designated namespace. Note that all our variables in the program being discussed are global in scope because we have not pre-declared them.
What we have seen in this section is an extremely simple example showing the use of packages. There are many other details that we need to know if we want to use packages effectively. For example, there is a mechanism to export, from the home package, variable and function names so that the names can be used without qualifiers in non-home packages.