print "I am in package _ _PACKAGE_ _\n"; # WRONG!
I am in package _ _PACKAGE_ _
Needing to figure out the caller's package arose more often in older
code that received as input a string of code to be
eval uated, or a filehandle, format, or directory
handle name. Consider a call to a hypothetical
runit function:
package Alpha;
runit('$line = <TEMP>');
package Beta;
sub runit {
my $codestr = shift;
eval $codestr;
die if $@;
}
Because runit was compiled in a different package
than was currently executing, when the eval runs,
it acts as though it were passed $Beta::line and
Beta::TEMP. The old workaround was to include your
caller's package first:
package Beta;
sub runit {
my $codestr = shift;
my $hispack = caller;
eval "package $hispack; $codestr";
die if $@;
}
That approach works only when $line is a global
variable. If it's lexical, that won't help at all. Instead, arrange
for runit to accept a reference to a subroutine:
package Alpha;
runit( sub { $line = <TEMP> } );
package Beta;
sub runit {
my $coderef = shift;
&$coderef( );
}
This not only works with lexicals, but has the added benefit of
checking the code's syntax at compile time, which is a major win.
Here's an example that reads and returns n lines
from a filehandle. The function qualifies the handle before working
with it.
open (FH, "<", "/etc/termcap") or die "can't open /etc/termcap: $!";
($a, $b, $c) = nreadline(3, "FH");
use Symbol ( );
use Carp;
sub nreadline {
my ($count, $handle) = @_;
my(@retlist,$line);
croak "count must be > 0" unless $count > 0;
$handle = Symbol::qualify($handle, (caller( ))[0]);
croak "need open filehandle" unless defined fileno($handle);
push(@retlist, $line) while defined($line = <$handle>) && $count--;
return @retlist;
}