Приглашаем посетить
Почтовые индексы (post.niv.ru)

Recipe 12.5. Determining the Caller's Package

PreviousChapter 12
Packages, Libraries, and Modules
Next
 

12.5. Determining the Caller's Package

Problem

You need to find out the current or calling package.

Solution

To find the current package:

$this_pack = __PACKAGE__;

To find the caller's package:

$that_pack = caller();

Discussion

The __PACKAGE__ symbol returns the package that the code is currently being compiled into. This doesn't interpolate into double-quoted strings:

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 evaluated, 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 will act 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 only works 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, it has the added benefit of checking the code's syntax at compile time, which is a major win.

If all that's being passed in is a filehandle, it's more portable to use the Symbol::qualify function. This function takes a name and package to qualify the name into. If the name needs qualification, it fixes it; otherwise, it's left alone. But that's considerably less efficient than a * prototype.

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;
}

If everyone who called your nreadline function passed in the filehandle as a typeglob *FH, as a glob reference \*FH, or using FileHandle or IO::Handle objects, you wouldn't need to do this. It's only the possibility of a bare "FH" that requires qualification.

See Also

The documentation for the standard Symbol module, also found in Chapter 7 of Programming Perl; the descriptions of the special symbols __FILE__ , __LINE__ , and __PACKAGE__ in perldata (1); Recipe 12.12


PreviousHomeNext
12.4. Making Variables Private to a ModuleBook Index12.6. Automating Module Clean-Up