Perl中的非本地返回(从调用者返回)

时间:2012-04-29 12:33:35

标签: perl

我有办法将我的来电者而不是返回我的来电者吗? 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

4 个答案:

答案 0 :(得分:6)

Continuation::Escape完全符合您的要求。然而,正如尼基尔指出的那样,Memoize是你真正需要的。

答案 1 :(得分:1)

看看CPAN模块Memoize - 通过交易空间来加快功能,这可能会解决您的问题。

答案 2 :(得分:0)

“我有没有办法从我的来电者那里回来而不是给我的来电者?”

是的,有几个。

  • 您可以使用goto跳回来。请参阅perldoc -f goto
  • 您可以使用evaldie进行更多控制跳转。请参阅perldoc -f evalperldoc -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();