【发布时间】:2018-12-30 03:18:30
【问题描述】:
Perl 有点太宽容了:如果你将额外的参数传递给subs,它们就会被忽略。
为避免这种情况,我想使用原型来确保每个sub 都被赋予了正确数量的参数。
只要我在使用原型之前声明它就可以了:
sub mysub($);
sub mysub2($);
mysub(8);
mysub(8,2); # Complain here
sub mysub($) {
mysub2($@);
}
sub mysub2($) {
if($_[0] == 1) {
mysub(2);
}
print $@;
}
但我真的很讨厌把它分开。我宁愿 Perl 阅读完整的文件,看看是否有进一步的声明。所以我想写这样的东西:
use prototypes_further_down; # This does not work
mysub(8);
mysub(8,2); # Complain here
sub mysub($) {
mysub2($@);
}
sub mysub2($) {
if($_[0] == 1) {
mysub(2);
}
print $@;
}
我能以某种方式让 Perl 这样做吗?
【问题讨论】:
-
从根本上说,你所问的都是不可能的。原型不添加参数检查;原型更改子调用的解析规则。因此,在进行子调用之前必须知道存在。
-
你为什么把你的 sub decls 放在首位?这只是邀请范围泄漏。因此,无论是您询问的原因还是为了防止 subs 捕获他们不应该捕获的 var,请将您的 subs 放在您的代码之前。
-
那又怎样?在极少数情况下使用前向声明。
-
如果你想要(一些相似的)参数检查,切换到使用“正确的”子例程签名。当使用无效数量的参数调用子例程时,这些会死掉(在运行时)。 perldoc.perl.org/perlsub.html
-
如果你不知道,从 v5.20 开始就有subroutine signatures,就是为了这个目的。有一个深入的讨论in Effective Perler。它们是实验性的,如果这会扼杀交易,那么我认为您将按照 Perl 的设计精神进行手动检查。有一些模块可以帮助检查(但对我来说,它们 add 有效)。原型并不是你想要的。