我正在尝试调用嵌套的递归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
答案 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->();
};