嵌套函数调用范围和语法

时间:2012-03-08 20:01:18

标签: perl syntax recursion scope

我正在尝试调用嵌套的递归perl函数,但我无法使用正确的语法。

问题:对嵌套函数执行递归调用的正确语法是什么(如果应该递归调用嵌套函数)?

答案:请参阅接受答案中建议的伪代码。

这是一个伪代码片段:

use Scalar::Util;
sub outerfunction {
  my $innerfunction = sub {
    # Do something
    innerfunction(); 
    # Do other things
  }; 
  Scalar::Util::weaken($innerfunction); 
  &$innerfunction(@_);
}; 

我试图调用内部函数如下(带有相应的错误消息):

innerfunction
  

未定义的子程序& main :: innerfunction

&innerfunction
  

未定义的子程序& main :: innerfunction

&$innerfunction
  

全局符号“$ innerfunction”需要显式包名称

我也尝试将内部函数声明为local,但收到以下内容:

  

全局符号“$ innerfunction”需要显式包名称

我对解释型语言没有多少经验,因此任何与内存/堆栈泄漏/损坏相关的附带注释或上述伪代码的其他危险(除递归系统限制之外)都会受到高度赞赏。

谢谢! 在Linux 2.6.34.7-61.fc13.x86_64上运行的perl v5.10.1

2 个答案:

答案 0 :(得分:14)

innerfunction()语法仅适用于已安装到符号表中的子例程(例如sub NAME {...}语法)。您需要将内部函数称为$innerfunction->()&$innerfunction(),但遇到问题的方法是使用$innerfunction词法的范围。

当您使用my声明变量时,该变量在语句结束后的范围内。所以你需要拆分你的声明:

 my $innerfunction;
    $innerfunction = sub {
        ...
        $innerfunction->();
        ...
    };

要用weaken打破循环引用,通常的模式是:

use Scalar::Util;
sub outer_function {
    my $weak_ref;
    $weak_ref = my $strong_ref = sub {
        # Do something
        $weak_ref->(); 
        # Do other things
    };
    Scalar::Util::weaken($weak_ref); 
    return $strong_ref;
};

现在,只要$strong_ref超出范围,子程序就会被垃圾收集。

答案 1 :(得分:4)

sub outer_function {
    local *inner_function = sub {
        # Do something
        inner_function(); 
        # Do other things
    };
    inner_function();
};

几乎和以下一样好,但更加清晰:

use Scalar::Util qw( weaken );
sub outer_function {
    my $weak_ref;
    my $strong_ref = sub {
        # Do something
        $weak_ref->(); 
        # Do other things
    };
    weaken($weak_ref = $strong_ref);  # Avoid memory leak.
    $strong_ref->();
};