使用 Perl 的原型有什么缺点吗?

Are there any drawbacks to using Perl's prototypes?

我会调用我的潜艇而不在参数列表周围使用括号。例如,我想使用

mypush \@list, $item;

而不是

mypush(\@list, $item);

为此,我用原型声明了我的潜艇。

sub mypush (+@) { push shift, @_ }

事实上,这也让我可以做到以下几点,但这只是一个额外的好处:

mypush @list, $item;

除了在代码中的任何地方使用 之前 使用原型声明子例程之外,在 Perl 中使用原型有什么严重的缺点吗?

代码对我来说看起来更清晰。但是一般来说,原型会在哪里出错呢?我什么时候会后悔?

您的问题没有实际意义,因为原型对括号的需求没有影响。只要 sub 在使用之前声明,parens 是可选的。

$ perl -E'
   sub foo { say @_; }
   foo "bar";
'
bar

$ perl -E'
   sub foo;
   foo "bar";
   sub foo { say @_; }
'
bar

请注意,省略括号有严重的缺点。

  1. 很容易不小心将错误的参数传递给子对象:

    $ perl -E'
       sub foo { say @_; }
       foo 9*6;
       foo (4+5)*6;
    '
    54
    9
    
  2. 代码中的错误可能会导致误导和混淆的错误消息。

    $ perl -E'foo bar "baz";'
    Can't locate object method "foo" via package "bar"
       (perhaps you forgot to load "bar"?) at -e line 1.
    

    Here 是您省略括号时出现的另一个古怪例子。

这些问题可以说比使用原型导致的问题更严重。使用其中任何一个 "features" 似乎都不明智;引入两组问题就更不用说了

最大的缺点之一是它使代码更难维护。似乎很少有人了解 Perl 原型实际上做了什么,因此围绕他们有很多猜测和货物崇拜。

不过请注意,Perl 5.20 添加了 subroutine signature feature。它仍然是实验性的,但它真的有点棒,而且是大多数人期望原型做的事情。而且,当我们添加类型约束时(哦,圣诞老人,求求你了,求求你了,圣诞节给我带那些,我保证我会很好!),我们将拥有我认为大多数人试图用原型做的事情(用我做的一些语法上):

sub foo (Int $foo, String $var, Int @array) { ... }