代码之家  ›  专栏  ›  技术社区  ›  Geo

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

  •  3
  • Geo  · 技术社区  · 15 年前

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

    sub new ($$$)
    {
       # code goes here
    }
    

    如果我创建这样的对象:

    my $parser = Parse::RecDescent->new($grammar);
    

    它将创建一个解析器,该方法将接收两个参数“parse::recscent”和$grammar,对吗?如果我试图创建一个对象,比如:

    Parse::RecDescent::new("Parse::RecDescent",$grammar)
    

    这将无法说“没有足够的参数用于parse::recdescent::new”,并且我理解此消息。我只传递两个参数。但是,我不明白为什么箭头版本有效。

    你能解释一下吗?

    1 回复  |  直到 15 年前
        1
  •  11
  •   Community CDub    8 年前

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

    perldoc perlsub :

    “&form”不仅使参数列表成为可选的,还禁用对您提供的参数的任何原型检查。部分原因是 历史原因,部分原因是如果你知道自己在做什么,就有一个方便的作弊方法。请参见下面的原型。

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

    Parse::RecDescent::new("Parse::RecDescent", $grammar) 在语法上是正确的,这是一种很难闻的调用构造函数的方法,现在您强制在该类(而不是祖先)中定义它。如果确实需要验证参数,请在方法内部进行验证:

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

    另请参见 this earlier question on prototypes 为什么他们通常不是一个好主意。