题
如何可以访问的符号表当前包中的对象被实例化?例如,我有这样的事情:
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
的祝福,但它仍然给了<=>的<=>而不是我。我们希望,这是一有点清晰了。
解决方案
您只是想 caller
'owning_package'
告诉您从它被称为包。 (在这里,我增加了一些标准的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)检查definedness槽,以及3)运行它,如果它被定义。
现在,如果你在一个包中创建一个对象,并在另一个使用它,这不会是太大的帮助。你可能会需要在构造函数中添加其他字段一样$x->{owning_package}
。
package MyMod;
#...
sub new {
#...
$self->{owning_package} = caller || 'main';
#...
}
现在'main'
将包含<=>。
其他提示
请参阅的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:\Temp> h No, you can't!
不隶属于 StackOverflow