我有办法将从我的来电者而不是返回我的来电者吗? e.g。
sub foo {
bar();
# this never gets executed
}
sub bar {
return_from_caller(5);
}
# This prints 5
print foo();
(理由:我正在写一个函数memoize_self,它在函数本身内记忆一个函数。我希望它能像这样工作:
sub complex_function {
my ($x, $y) = @_;
memoize_self({key => $y, expires_in => '5min'));
# compute $result
return $result;
}
memoize_self将检查其缓存,如果它被命中,则从其调用者返回缓存的值。否则,它将重新调用该函数(使用动态范围的var来避免明显的无限循环),将返回值存储在缓存中并再次返回。
如果没有从调用者返回的能力,我可能会使用$ _并以这种方式编写它:
return $_ if memoize_self({key => $y, expires_in => '5min'));
但这是额外的噪音,也没有考虑上下文。)
编辑:对于合理建议的人Memoize - 是的,我应该说,我很了解这个模块。我正在基于CHI编写一个更现代,更有特色的Memoize版本。
但是就这个问题而言,有些情况下,从在函数内而不是在函数中进行记忆是有用的(Memoize只执行后者)。它可以轻松自定义缓存键和/或确定是否要为此特定调用进行任何记忆。 e.g。
sub complex_function {
my $key = ...; # normalize arguments
if (...) { # is it worth memoizing in this case?
memoize_self({key => $key});
}
}
我也喜欢它在函数中被包裹的方式,而不是在外面创建自己的行,ala state variables。
答案 0 :(得分:6)
Continuation::Escape完全符合您的要求。然而,正如尼基尔指出的那样,Memoize是你真正需要的。
答案 1 :(得分:1)
看看CPAN模块Memoize - 通过交易空间来加快功能,这可能会解决您的问题。
答案 2 :(得分:0)
“我有没有办法从我的来电者那里回来而不是给我的来电者?”
是的,有几个。
goto
跳回来。请参阅perldoc -f goto
。eval
和die
进行更多控制跳转。请参阅perldoc -f eval
和perldoc -f die
。goto
而不是以正常方式呼叫您的潜水艇。执行此操作时,它将返回到goto
调用方的子服务器。请参阅perldoc -f goto
。当然,大多数人会告诉你重写所有内容以避免使用getos并让那些维护代码的人生活更轻松,但他们曾为你做过什么?
答案 3 :(得分:0)
另一个解决方案是使用Want模块的double_return方法,这会使你的下一个返回弹出两个调用框:
#!/usr/bin/env perl
use warnings;
use strict;
use Want;
sub foo {
Want::double_return;
return 11;
}
sub bar {
foo();
# never executed
return 55;
}
# prints 11;
print bar();