Por que as duas versões deste código não estão falhando na verificação -c perl?

StackOverflow https://stackoverflow.com/questions/2255495

  •  20-09-2019
  •  | 
  •  

Pergunta

o new método de Parse::RecDescent tem este protótipo:

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

E se eu criar um objeto como este:

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

Ele criará um analisador e o método receberá 2 parâmetros "Parse :: RecDescent" e $ Grammar, certo? Se eu tentar criar um objeto como:

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

Isso falhará dizendo "argumentos insuficientes para analisar :: Recdescent :: New", e eu entendo esta mensagem. Estou apenas passando 2 parâmetros. No entanto, não entendo por que a versão de seta funciona.

Você pode explicar?

Foi útil?

Solução

Os protótipos de função não são verificados quando você o chama de método de estilo OO. Além disso, você ignora a verificação de protótipos quando liga para um sub &, como em &sub(arg0, arg1..);

A partir de Perldoc Perlsub:

O formulário "&" não apenas torna a lista de argumentos opcional, como também desativa qualquer protótipo de verificação dos argumentos que você fornece. Isso é parcialmente por razões históricas e em parte por ter uma maneira conveniente de trapacear se você souber o que está fazendo. Veja protótipos abaixo.

As chamadas de método também não são influenciadas por protótipos, porque a função a ser chamada é indeterminada no tempo de compilação, uma vez que o código exato chamado depende da herança.

Enquanto Parse::RecDescent::new("Parse::RecDescent", $grammar) é sintaticamente correto, essa é uma maneira bastante fedorenta de chamar o construtor, e agora você está forçando a ser definido nessa classe (e não em um ancestral). Se você realmente precisar validar seus argumentos, faça -o dentro do método:

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

Veja também Esta pergunta anterior sobre protótipos E por que eles geralmente não são uma ótima idéia.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top