5.4 Packages and Subroutines
A subroutine declared in a package is available only within the package without qualification by the package name. We can always qualify with the package name although it is redundant to qualify a subroutine’s name in the package in which it is defined. In another package, the subroutine cannot be called without the package name qualifier. The following program illustrates these findings.
Program 5.11
#!/usr/bin/perl
#file sub.pl
use strict;
sub hello{
print "Hello: I am the main man!\n"
}
hello;
&main::hello;
package Tommy;
&hello;
&main::hello;
The output of the program is given below.
Hello: I am the main man! Hello: I am the main man! Undefined subroutine &Tommy::hello called at sub.pl line 14.
Here, there are four calls to the subroutine hello and the third call causes runtime error. Note that when a subroutine in another package is called, Perl does not check if it exists during compilation, but only during execution. When a program gives an error and exits, it is possible to capture the error in order to handle it in some fashion to take care of the situation, and not let Perl runtime environment exit automatically. We can use the eval function to do that. eval can take a sequence of statements enclosed in
braces and execute them. The statements inside the eval are parsed at the same time as the rest of the code. The code inside the eval is executed when the rest of the code is executed, i.e., in the context of the current Perl program. The value returned by eval is the value of the last contained statement. If there is a syntax error that results within the eval after execution (it is possible for one to construct a statement on the fly inside the eval) or there is a runtime
error, or a die statement is executed within the eval, an undefined value is returned by eval, and the special variable $@ is set. $@ contains the error message. If there is no error inside the eval, $@ has the null or empty value. Any error string printed to STDERR (usually, the screen or the terminal) by the contained statements are still printed. Thus,
eval can trap otherwise fatal errors. Actions can be taken by a program based on the error.
The following is a rewrite of the previous program where errors are trapped from two evals.
Program 5.12
#!/usr/bin/perl
#file sub1.pl
use strict;
my $error;
sub hello{
print "Hello: I am the main man!\n"
}
hello;
&main::hello;
package Tommy;
eval{&hello} or warn "$@";
if ($@){print "Error in the call to hello\n";}
eval{&main::hello} or warn "$@";
if ($@){print "Error in the call to main::hello\n";}
It shows that the calls to hello in the main package are good calls and executed. In the Tommy package, the first call is unacceptable because the name of the subroutine is not qualified by the package name. The error is captured and the handler simply prints a string though in practice, it may be more complex. However, as we see the program does not die, and continues to the next statement. The last call to hello is fully qualified with the name of the package.
Hello: I am the main man! Hello: I am the main man! Undefined subroutine &Tommy::hello called at sub1.pl line 15. Error in the call to hello Hello: I am the main man!