ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы.



Advanced Perl Programming

Advanced Perl ProgrammingSearch this book
Previous: 5.8 ResourcesChapter 6Next: 6.2 Packages and Files
 

6. Modules

Life is a struggle with things to maintain itself among them. Concepts are the strategic plan we form in answer to the attack.

- Jose Ortega y Gasset, The Revolt of the Masses

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.

6.1 Basic Package

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 \n";
}
sub withdraw {
    my ($amount)= @_;
    $total -= $amount; 
    $total = 0  if $total < 0;
    print "You now have $total dollars \n";
}

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.

6.1.1 Packages and Variables

In Chapter 3, Typeglobs and Symbol Tables, 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 the section "Accessing the Symbol Table" 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.

6.1.2 Symbolic References

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, Object Orientation: The Next Few Steps.