如果我有一个带有此代码段的Perl模块Resounces.pm
,请说明my $my_class = new MY_CLASS;
our resource => { '/list' => $my_class->list_files() };
那么我可以在另一个类似的perl脚本中调用这个资源变量吗?
use Resources;
$Resources::resource->{'/list'};
我打算在使用最后一个语句时执行list_files()方法。这甚至可能吗?
答案 0 :(得分:4)
一种选择是使用匿名子:
package Resources;
my $my_class = new MY_CLASS;
our $resource = { '/list' => sub { $my_class->list_files(@_); } };
...
package main;
# dereference the code ref
&{$Resources::resource->{'/list'}};
# or call it:
$Resources::resource->{'/list'}();
如果您更改$my_class
引用,它也将在匿名函数中更改。这可能是你想要的;如果没有,请继续阅读绑定对象和方法的函数(bindMethod
)。
如果您不希望匿名函数出现在堆栈中:
our $resource = { '/list' => sub { unshift @_, $my_class;
goto &MyClass::list_files; } };
请注意,这种形式的goto
不是通常的goto语句 - 它是tail call。
你可以定义一个帮助方法来设置绑定,但老实说它不会给你带来太大的帮助。
sub bindMethod {
my ($obj, $meth) = @_;
return sub { unshift @_, $obj; goto &{$meth}; }
}
my $my_class = new MyClass;
our $resource = { '/list' => bindMethod($my_class, \&MyClass::list_files) };
这是bindMethod
的版本,不需要使用方法名称指定类。
sub bindMethod {
my ($obj, $meth) = @_;
if (! ref $meth) {
my $class = ref $obj;
$meth = \&{"${class}::$meth"};
}
return sub { unshift @_, $obj; goto &{$meth}; }
}
...
my $my_class = new MyClass;
our $resource = { '/list' => bindMethod($my_class, 'list_files') };