[英]How can I pass a module's function as a reference to another module in Perl?
How can I pass a reference to a module's function as parameter in a function call of another module? 如何在另一个模块的函数调用中将模块函数的引用作为参数传递?
I tried the following (simple example): 我尝试了以下(简单示例):
This is the module that has a function (process_staff) that takes as a parameter a function reference (is_ok). 这是具有函数(process_staff)的模块,该函数将函数引用(is_ok)作为参数。
#!/usr/bin/perl
use strict;
use warnings;
package Objs::Processing;
sub new {
my ($class) = @_;
bless {} ;
}
sub process_staff {
my ($employee, $func) = @_;
if($func->is_ok($employee)) {
print "Is ok to process\n";
}
else {
print "Not ok to process\n";
}
}
1;
This is the module that implements the passed function (is_ok) 这是实现传递函数的模块(is_ok)
#!usr/bin/perl
use strict;
use warnings;
package Objs::Employee;
my $started;
sub new {
my ($class) = @_;
my $cur_time = localtime;
my $self = {
started => $cur_time,
};
print "Time: $cur_time \n";
bless $self;
}
sub get_started {
my ($class) = @_;
return $class->{started};
}
sub set_started {
my ($class, $value) = @_;
$class->{started} = $value;
}
sub is_ok {
my ($emp) = @_;
print "In is ok I received:\n";
use Data::Dumper;
print Dumper($emp);
return 1;
}
This is my test script that I run: 这是我运行的测试脚本:
#!/usr/bin/perl
use strict;
use warnings;
use Objs::Manager;
use Objs::Processing;
my $emp = Objs::Manager->new('John Smith');
use Data::Dumper;
print Dumper($emp);
my $processor = Objs::Processing->new();
$processor->process_staff(\&$emp->is_ok); #error is here
I get a: 我得到一个:
Not a CODE reference at testScript.pl line 14.
I also tried: $processor->process_staff(\\&$emp->is_ok());
我也尝试过:
$processor->process_staff(\\&$emp->is_ok());
but also still does not work. 但仍然无法正常工作。
What am I doing wrong here 我在这做错了什么
You appear to want to pass an object and a method to call on it; 您似乎想要传递一个对象和一个方法来调用它; the easiest way to do that would be:
最简单的方法是:
$processor->process_staff( sub { $emp->is_ok } );
where process_staff looks like: process_staff的位置如下:
sub process_staff {
my ($self, $func) = @_;
if ( $func->() ) {
...
or you can pass the reference and the object separately: 或者您可以单独传递引用和对象:
sub process_staff {
my ($self, $emp, $method) = @_;
if ( $emp->$method() ) {
...
$processor->process_staff( $emp, $emp->can('is_ok') );
I think this could work with: 我认为这可以用于:
$processor->process_staff(\&Objs::Employee::is_ok);
where you pass in the method ref. 你传入方法ref的地方。
and where you currently have 你现在的位置
if( $func->is_ok($employee) ) {
you need 你需要
if( $func->( $employee ) ) {
This is because you cannot reference named methods simply from an object, by the syntax \\&$obj->method
. 这是因为您无法通过语法
\\&$obj->method
仅从对象引用命名\\&$obj->method
。
However, in your example code it is not at all clear why you don't do this instead: 但是,在您的示例代码中,您完全不清楚为什么不这样做:
if( $employee->is_ok() ) {
in which case you would not need to reference the method to call in process_staff
at all. 在这种情况下,您根本不需要引用在
process_staff
中调用的方法。 There are also other ways to achieve the same method indirection that might give you better encapsulation in future. 还有其他方法可以实现相同的方法间接,可能会在将来为您提供更好的封装。
In this expression: 在这个表达式中:
$processor->process_staff(\&$emp->is_ok);
You are saying "call the method $emp->is_ok
, take the return value, treat it as a CODE
reference, dereference it, and return a reference to that. That doesn't work, since the return value from that sub is not a CODE
reference. 你说的是“调用方法
$emp->is_ok
,获取返回值,将其视为CODE
引用,取消引用它,并返回对它的引用。这不起作用,因为该子句的返回值不是CODE
参考。
To do what you want, you can use a reference to an anonymous sub to wrap the call to your object method: 要执行您想要的操作,您可以使用对匿名子的引用来包含对对象方法的调用:
$processor->process_staff( sub { $emp->is_ok } );
You can pass anonymous coderef which returns result from desired method, 您可以传递匿名coderef,它返回所需方法的结果,
$processor->process_staff(sub{ $emp->is_ok(@_) });
@_
can be dropped as is_ok
method doesn't take any arguments. 可以删除
@_
因为is_ok
方法不接受任何参数。
It's not specifically what you asked for, but I think you simply need the following: 这不是你要求的具体内容,但我认为你只需要以下内容:
sub process_staff {
my ($self, $emp) = @_;
if ($emp->is_ok()) {
print "Is ok to process\n";
}
else {
print "Not ok to process\n";
}
}
$processor->process_staff($emp);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.