【发布时间】:2013-07-19 06:15:56
【问题描述】:
File::Find 和 wanted 子程序
这个问题比原来的标题(“子程序的原型和前向声明”!)要简单得多。我希望答案,无论多么简单,都能帮助我理解子例程/函数、原型和范围以及File::Find 模块。
使用 Perl,子程序几乎可以出现在任何地方,您通常不需要进行前向声明(除非子程序声明了一个原型,我不确定如何在 Perl 中以“标准”方式进行) .对于我通常使用 Perl 所做的事情,这些不同的运行方式之间几乎没有区别 somefunction:
sub somefunction; # Forward declares the function
&somefunction;
somefunction();
somefunction; # Bare word warning under `strict subs`
我经常使用find2perl 生成代码,我将这些代码植入/破解到脚本的某些部分。这很可能是不好的风格,现在我的脏衣服是公开的,但就这样吧:-) 对于File::Find,wanted 函数是必需的子例程 - find2perl 创建它并将sub wanted; 添加到生成的脚本中创建。有时,当我编辑脚本时,我会从sub wanted 中删除“sub”,它最终会变成&wanted; 或wanted();。但是如果没有sub wanted; 前向声明表,我会收到以下警告:
Use of uninitialized value $_ in lstat at findscript.pl line 29
我的问题是:为什么会发生这种情况,这是一个真正的问题吗?这“只是一个警告”,但我想更好地理解它。
- 文档和代码说
$_本地化在sub wanted {}内部。如果我使用wanted();而不是sub wanted;,为什么它会未定义? -
wanted是否在某处使用原型?我在Find/File.pm中遗漏了什么明显的东西吗? - 是不是因为
wanted返回了代码引用? (???)
我的猜测是前向声明表单以某种方式“初始化”wanted,这样第一次使用就没有空的默认变量。我想这就是原型——即使是 Perl 原型,比如它们存在的——也可以工作的方式。我尝试通过搜索 Perl 源代码来了解在使用 sub function 而不是 function() 调用函数时 sub 正在做什么,但这可能超出了我的理解范围。
非常感谢任何加深(和加快)我对此理解的帮助。
编辑:这是我使用find2perl 的输出创建的recent example script here on Stack Overflow。如果你从sub wanted; 中删除sub,你应该会得到同样的错误。
编辑:正如我在下面的评论中指出的(但我也会在这里标记它):几个月来我一直在使用Path::Iterator::Rule 而不是File::Find。它需要perl >5.10,但我永远不必在具有奇怪、“永不升级”、5.8.* 唯一策略的站点上部署生产代码,因此Path::Iterator::Rule 已成为我永远不想放弃的模块之一。 Path::Class 也很有用。干杯。
【问题讨论】:
-
转发声明函数与调用函数不同。声明它不会执行函数内部的代码。所以你不能简单地将
sub wanted;替换为wanted();和co。 -
几个月来我一直在使用
Path::Iterator::Rule而不是File::Find。