帮助在 Perl 中传递对类子例程的引用
我正在尝试将一个例程传递给 Perl 模块中的另一个子例程。但是当我传递子引用时,传入的 ref 不再具有对象数据。也许这样是不可能做到的。我有疑问的那一行是下面的“除非”行:
sub get_flag_end {
my $self = shift;
return ( -e "$self->{file}" );
}
sub wait_for_end {
my $self = shift;
my $timeout = shift;
my $poll_interval = shift;
# Is it even possible to pass the oject subroutine and retain the objects data?
#unless ( $self->timeout( $timeout, $poll_interval, $self->get_flag_end ) ) { # does not work
unless ( $self->timeout( $timeout, $poll_interval, \&get_flag_end ) ) { # call happens but members are empty
die "!!!ERROR!!! Timed out while waiting for wait_for_end: timeout=$timeout, poll_interval=$poll_interval \n";
}
}
sub timeout {
my $self = shift;
my $timeout = shift;
my $poll_interval = shift;
my $test_condition = shift;
until ($test_condition->() || $timeout <= 0) {
$timeout -= $poll_interval;
sleep $poll_interval;
}
return $timeout > 0; # condition was met before timeout
}
我知道我可以更改“get_flag_end”例程以将该值作为子例程的参数,但是如果“get_flag_end”中完成了一堆事情怎么办我需要该对象的更多成员。我稍微简化了代码,使其更容易理解。
I am trying to pass a routine to another subroutine within a Perl module. But when I pass the sub reference the passed in ref no longer has the object data. Maybe its not possible to do it this way. The line I have a question about is the "unless" lines below:
sub get_flag_end {
my $self = shift;
return ( -e "$self->{file}" );
}
sub wait_for_end {
my $self = shift;
my $timeout = shift;
my $poll_interval = shift;
# Is it even possible to pass the oject subroutine and retain the objects data?
#unless ( $self->timeout( $timeout, $poll_interval, $self->get_flag_end ) ) { # does not work
unless ( $self->timeout( $timeout, $poll_interval, \&get_flag_end ) ) { # call happens but members are empty
die "!!!ERROR!!! Timed out while waiting for wait_for_end: timeout=$timeout, poll_interval=$poll_interval \n";
}
}
sub timeout {
my $self = shift;
my $timeout = shift;
my $poll_interval = shift;
my $test_condition = shift;
until ($test_condition->() || $timeout <= 0) {
$timeout -= $poll_interval;
sleep $poll_interval;
}
return $timeout > 0; # condition was met before timeout
}
I know that I could change the "get_flag_end" routine to take the value as an argument to the subroutine but what if there was a bunch of stuff done in "get_flag_end" and I needed more members from the object. I simplified the code a bit to make it a little easier to follow.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
只需创建一个闭包并将其传入:
Update:
另一个选项是,由于
timeout
是同一类的方法,因此传入方法名称。Just make a closure and pass that in:
Update:
The other option is, since
timeout
is a method of the same class, pass in a method name.在您的
$test_condition->()
行中,您正在调用子例程,但不向其传递任何参数。您的意思很可能是$test_condition->($self)
或者可能是$self->$test_condition
这是您的代码的重构,纠正了一些其他问题:
根据您的实现的其余部分,创建一个知道其调用者的子例程可能会更好。您可以在 Perl 中使用闭包执行此操作:
这里创建了一个新的子例程,它会记住
$self
的值。您可以不带参数调用它$test_condition->()
In your
$test_condition->()
line, you are calling the subroutine but not passing it any arguments. Chances are what you meant was$test_condition->($self)
or perhaps as$self->$test_condition
Here is a refactor of your code, correcting a few other issues:
Depending on the rest of your implementation, creating a subroutine that knows its invocant might be better. You can do this in Perl with a closure:
Here a new subroutine is created, which remembers the value of
$self
. You would call it without arguments$test_condition->()