1

如何访问实例化对象的当前包的符号表?例如,我有这样的事情:

my $object = MyModule->new;
# this looks in the current package, to see if there's a function named run_me
# I'd like to know how to do this without passing a sub reference
$object->do_your_job;

如果在do_your_job我使用的实现中__PACKAGE__,它将在MyModule包中搜索。我怎样才能让它看起来在正确的包装中?

编辑:我会尽量让这个更清楚。假设我有以下代码:

package MyMod;

sub new {
    return bless {},$_[0]
}

sub do_your_job {
    my $self = shift;
    # of course find_package_of is fictional here
    # just for this example's sake, $pkg should be main
    my $pkg = find_package_of($self);
    if(defined &{ $pkg . '::run_me' }) {
        # the function exists, call it.
    }
}

package main;

sub run_me {
   print "x should run me.\n";
}

my $x = MyMod->new;

# this should find the run_me sub in the current package and invoke it.
$x->do_your_job;

现在,$x应该以某种方式注意到这main是当前包,并搜索它的符号表。我尝试使用Scalar::Util's'blessed,但它仍然给了我MyModule而不是main。希望这现在更清楚了。

4

2 回答 2

6

你只想caller

caller告诉你调用它的包。(这里我添加了一些标准的 perl。)

use Symbol qw<qualify_to_ref>;
#...
my $pkg = caller;

my $symb   = qualify_to_ref( 'run_me', $pkg );
my $run_me = *{$symb}{CODE};
$run_me->() if defined $run_me;

查找它并查看它是否已定义然后查找它以调用它会复制它,因为标准 perl 不执行公共子表达式消除,因此您不妨 1)检索它,以及 2)检查插槽的定义性,和 3) 如果已定义,请运行它。

现在,如果您在一个包中创建一个对象并在另一个包中使用它,那将不会有太大帮助。您可能需要'owning_package'在构造函数中添加一个附加字段。

package MyMod;

#...
sub new { 
    #...
    $self->{owning_package} = caller || 'main';
    #...
}

现在$x->{owning_package}将包含'main'.

于 2009-11-30T21:33:50.740 回答
1

请参阅perldoc -f 调用者

#!/usr/bin/perl

package A;
use strict; use warnings;

sub do_your_job {
    my ($self) = @_;
    my ($pkg) = caller;
    if ( my $sub = $pkg->can('run_me') ) {
        $sub->();
    }
}

package B;
use strict; use warnings;

sub test {
    A->do_your_job;
}

sub run_me {
    print "No, you can't!\n";
}

package main;

use strict; use warnings;

B->test;

输出:

C:\温度> h
不,你不能!
于 2009-11-30T21:13:08.223 回答