【发布时间】:2012-03-08 20:01:17
【问题描述】:
我正在尝试调用嵌套递归 perl 函数,但我无法使用正确的语法。
问题:对嵌套函数执行递归调用的正确语法是什么(如果嵌套函数应该被递归调用)?
答案:参考已接受答案中建议的伪代码。
这是一个伪代码sn-p:
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”需要明确的包名
我也尝试将内部函数声明为本地函数,但收到以下内容:
全局符号“$innerfunction”需要明确的包名
我在解释语言方面没有太多经验,因此任何与内存/堆栈泄漏/损坏或上述伪代码的其他危险(递归系统限制除外)相关的附带评论也将不胜感激。
谢谢! 在 Linux 2.6.34.7-61.fc13.x86_64 上运行的 perl v5.10.1
【问题讨论】:
-
在引用上使用
weaken的目的是什么? -
遇到了一些帖子,这些帖子建议使用它来防止过时的引用导致内存泄漏,当函数引用超出范围时,perl 解释器可能会忽略这些引用。不过,它似乎不会影响潜在的问题。如果不建议使用weak(),请纠正我的理解。
-
听起来像是过早的优化。你有内存泄漏的问题吗?我认为像子程序这样基本的东西可以很好地防止泄漏。
-
@TLP,
weaken在创建递归闭包时是必需的。如果闭包持有对自身的强引用,那么它永远不会被垃圾收集(直到解释器关闭)。这可能不是严重的泄漏(这取决于调用outerfunction的频率),但它会是内存泄漏。 -
@TLP,
my $foo; sub foo { $foo } $foo = \&foo;确实遇到了同样的问题(即$foo和&foo在全球破坏之前不会被释放),但是 1)你永远不会这样做,并且2)foo在全局销毁之前不会超出范围,所以它没有实际意义。
标签: perl syntax recursion scope