Perl 对象如何访问当前包的符号表?

Perl 对象如何访问当前包的符号表?,perl,symbol-table,Perl,Symbol Table,如何访问实例化对象的当前包的符号表?例如,我有这样的东西: 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时,

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

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
时,我使用
\u包
,它将在
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
,但它仍然给了我
MyModule
,而不是
main
。希望这一点现在更清楚了。

请参见:

输出:

C:\Temp> h No, you can't! C:\Temp>h 不,你不能! 见:

输出:

C:\Temp> h No, you can't! C:\Temp>h 不,你不能! 你只是想

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

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

你只是想

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


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

有趣的西南:)!我想很明显,这是我第一次想要的。@Geo好吧,那时候编辑历史是件好事。我的意思是,有三个通情达理的人误解了你的要求,你必须澄清。这就是我添加额外澄清的原因。我注意到这不是我想要的。有趣的希南:)!我想很明显,这是我第一次想要的。@Geo好吧,那时候编辑历史是件好事。我的意思是,有三个通情达理的人误解了你的要求,你必须澄清。这就是我添加额外澄清的原因。我注意到这并不是我想要的。当遇到这样的问题时,我首先转向perlfunc的Perl函数分类部分。它有很好的内置列表,可以轻松地浏览可能与当前问题相关的内容。在这种情况下,标记为“与范围相关的关键字”的部分有8项要检查。第一个是调用方。既然我们已经确定了正确的答案,我很想知道你为什么要这么做。在绝大多数情况下,让一个方法访问实例化对象的包的符号表对我来说是一个非常糟糕的主意。我看到了这个Win32::GUI教程,我想象这就是
Main\u Terminate
的实现方式。@Geo:你可能是对的。(至少在精神上,Win32::GUI主要是XS代码。)我一直讨厌依赖命名约定来实现回调的GUI工具包。我想知道它是如何实现的。。。知道是什么使它起作用似乎很有趣。当遇到这样的问题时,我首先转向perlfunc的Perl函数分类部分。它有很好的内置列表,可以轻松地浏览可能与当前问题相关的内容。在这种情况下,标记为“与范围相关的关键字”的部分有8项要检查。第一个是调用方。既然我们已经确定了正确的答案,我很想知道你为什么要这么做。在绝大多数情况下,让一个方法访问实例化对象的包的符号表对我来说是一个非常糟糕的主意。我看到了这个Win32::GUI教程,我想象这就是
Main\u Terminate
的实现方式。@Geo:你可能是对的。(至少在精神上,Win32::GUI主要是XS代码。)我一直讨厌依赖命名约定来实现回调的GUI工具包。我想知道它是如何实现的。。。知道是什么使它起作用似乎很有趣。而且是:)
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;
package MyMod;

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