为什么这个代码的两个版本都没有通过-c Perl检查失败?

Geo*_*Geo 3 oop perl syntax-checking

有这个原型的new方法Parse::RecDescent:

sub new ($$$)
{
   # code goes here
}
Run Code Online (Sandbox Code Playgroud)

如果我创建这样的对象:

my $parser = Parse::RecDescent->new($grammar);
Run Code Online (Sandbox Code Playgroud)

它会创建一个解析器,该方法将接收2个参数"Parse :: RecDescent"和$ grammar,对吧?如果我尝试创建一个像这样的对象:

Parse::RecDescent::new("Parse::RecDescent",$grammar)
Run Code Online (Sandbox Code Playgroud)

这将失败说"没有足够的Parse :: RecDescent :: new参数",我理解这个消息.我只传递了2个参数.但是,我不明白为什么箭头版本有效.

你可以解释吗?

Eth*_*her 11

当您将其称为OO样式方法时,不会检查函数原型.此外,当您使用&调用sub时,可以绕过原型检查,如下所示&sub(arg0, arg1..);

来自perldoc perlsub:

"&"形式不仅使参数列表可选,而且还禁用对您提供的参数的任何原型检查.这部分是出于历史原因,部分原因在于,如果你知道自己在做什么,有一种方便的作弊行为.请参阅下面的原型.

方法调用也不受原型的影响,因为要调用的函数在编译时是不确定的,因为调用的确切代码依赖于继承.

虽然Parse::RecDescent::new("Parse::RecDescent", $grammar)在语法上是正确的,但这是调用构造函数的一种非常臭的方式,现在你强迫它在该类中定义(而不是在祖先中).如果您确实需要验证您的参数,请在方法内部执行:

sub new
{
    my ($class, @args) = @_;
    die "Not enough arguments passed to constructor" if @args < 2;
    # ...
}
Run Code Online (Sandbox Code Playgroud)

另见前面关于原型的问题,以及为什么它们通常不是一个好主意.