¿Por qué no están las dos versiones de este código no comprueba la -c Perl?
-
20-09-2019 - |
Pregunta
El método de new
Parse::RecDescent
tiene este prototipo:
sub new ($$$)
{
# code goes here
}
y si puedo crear un objeto como éste:
my $parser = Parse::RecDescent->new($grammar);
se creará un programa de análisis, y el método recibirá 2 parámetros "Parse :: RecDescent" y $ gramática, ¿verdad? Si trato de crear un objeto como:
Parse::RecDescent::new("Parse::RecDescent",$grammar)
este fallará dicho "no hay suficientes argumentos para Parse :: :: RecDescent nueva", y entiendo este mensaje. Yo sólo estoy de paso 2 parámetros. Sin embargo, no entiendo por qué funciona la versión flecha.
Puede explicar?
Solución
Los prototipos de función no se comprueban cuando se llama como un método de estilo OO. Además, se omite la comprobación de prototipo cuando se llama a un sub con Y, como en &sub(arg0, arg1..);
No sólo el "y" forma a hacer la lista de argumentos opcionales, también se desactiva cualquier prototipo de la comprobación de argumentos le proporcionan. Esto es en parte para razones históricas, y en parte para tener una forma conveniente de hacer trampa si usted sabe lo que está haciendo. Ver Prototipos a continuación.
llamadas a métodos no están influenciados por prototipos o bien, porque la función de ser llamado es indeterminado en tiempo de compilación, ya que el código exacto llamada depende de la herencia.
Mientras Parse::RecDescent::new("Parse::RecDescent", $grammar)
es sintácticamente correcta, que es una manera bastante mal olor de una llamada al constructor, y ahora que están obligando a que se defina en esa clase (en lugar de en un antepasado). Si realmente necesita para validar sus argumentos, hacerlo dentro del método:
sub new
{
my ($class, @args) = @_;
die "Not enough arguments passed to constructor" if @args < 2;
# ...
}
esta pregunta anterior sobre prototipos y por qué no están por lo general una gran idea.