Toma un ejemplo más simple
package Foo { sub new { die 7 } };
package Bar { sub new { die 42 } };
sub Foo { "Bar" }
Foo->new();
En el ejemplo anterior, la constante se Fooresuelve en "Bar", por lo que esto llama "Bar"->newno "Foo"->new. ¿Cómo se detiene la resolución de la subrutina? Puedes citarlo.
"Foo"->new();
En cuanto a la implicación del rendimiento, las cosas no empeoran al usar una cadena en lugar de una palabra desnuda. He confirmado que el optree generado por O=Deparsees el mismo. Entonces, como regla general, parece que es mejor citar los nombres de clase si valoras la corrección.
Esto se menciona en Programming Perl (lamentablemente en el contexto de la invocación indirecta de métodos )
... así que le diremos que casi siempre puede salirse con un nombre de clase desnudo, siempre que dos cosas sean ciertas. Primero, no hay una subrutina con el mismo nombre que la clase. (Si sigue la convención de que los nombres de subrutinas como newstart minúsculas y los nombres de clase como ElvenRingstart mayúsculas , esto nunca será un problema). En segundo lugar, la clase se cargó con uno de
use ElvenRing;
require ElvenRing;
Cualquiera de estas declaraciones asegura que Perl sabe que ElvenRinges un nombre de módulo, lo que obliga a que cualquier nombre simple como newantes del nombre de la clase ElvenRingse interprete como una llamada al método, incluso si usted declara una newsubrutina propia en el paquete actual.
Y eso tiene sentido: la confusión aquí solo puede ocurrir si sus subrutinas (generalmente en minúsculas) tienen el mismo nombre que una clase (generalmente en mayúsculas). Esto solo puede suceder si viola esa convención de nomenclatura anterior.
tldr; Probablemente sea una buena idea citar sus nombres de clase, si los conoce y valora la corrección sobre el desorden.
Nota al margen: alternativamente, puede detener la resolución de una palabra sin formato a una función fijando ::a al final de la misma, por ejemplo en lo anterior Foo::->new.
Gracias a Ginnz en reddit por señalarme esto , y a Toby Inkster por el comentario (aunque no tenía sentido para mí en la primera lectura).
Foo::->new, como aprendí de ikegami.Foo::tiene la ventaja de que avisa siFoono es un paquete existenteFoo->se puede esperar que sepa que no hay tal subrutina en su paquete. Pero si está utilizando Try :: Tiny y otros módulos externos de cpan / other, ¿quién puede decir si uno de ellos está usando un paquete Try y, de ser así, si hay un sub Tiny en él?Citar explícitamente el nombre de la clase en lugar de usar una palabra desnuda (que se trata como una cadena) es una de las tres formas de evitar la ambigüedad sintáctica. La sección Métodos de clase de invocación de la documentación de perlobj explica.
Vea este extraño caso en acción con la demostración a continuación.
Su salida es
El resto de la sección de documentación mencionada anteriormente muestra cómo protegerse contra comportamientos sorprendentes o errores involuntarios.
Aplicando a su pregunta, todas las llamadas a continuación son equivalentes.
Añadir
::al final tiene la ventaja de producir una advertencia útil. Digamos que accidentalmente escribisteEso produce
fuente