Veja um exemplo mais simples
package Foo { sub new { die 7 } };
package Bar { sub new { die 42 } };
sub Foo { "Bar" }
Foo->new();
No exemplo acima, a constante Foo
resolve para "Bar", portanto, isso "Bar"->new
não chama "Foo"->new
. Como você impede a sub-rotina de resolver? Você pode citá-lo.
"Foo"->new();
Quanto à implicação no desempenho, as coisas não são piores usando uma string em vez de uma palavra de barra. Confirmei que o optree gerado por O=Deparse
é o mesmo. Como regra geral, parece que é melhor citar os nomes de classe se você valoriza a correção.
Isso é mencionado em Program Perl, (infelizmente no contexto da invocação indireta de método )
... portanto, diremos que você quase sempre pode se dar bem com um nome de classe, desde que duas coisas sejam verdadeiras. Primeiro, não há sub-rotina com o mesmo nome que a classe. (Se você seguir a convenção de que nomes de sub-rotinas como new
iniciar em minúsculas e nomes de classe como ElvenRing
iniciar em maiúsculas , isso nunca será um problema). Segundo, a classe foi carregada com um dos
use ElvenRing;
require ElvenRing;
Qualquer uma dessas declarações garante que o Perl sabe que ElvenRing
é um nome de módulo, o que força qualquer nome simples, como new
antes do nome da classe, ElvenRing
a ser interpretado como uma chamada de método, mesmo se você declarar uma new
sub - rotina própria no pacote atual.
E isso faz sentido: a confusão aqui só pode acontecer se suas sub-rotinas (normalmente em minúsculas) tiverem o mesmo nome que uma classe (geralmente em maiúsculas). Isso só pode acontecer se você violar a convenção de nomenclatura acima.
tldr; provavelmente é uma boa idéia citar seus nomes de classe, se você os conhece e valoriza a correção em detrimento da confusão.
Nota lateral: como alternativa, você pode interromper a resolução de uma palavra de barra em uma função, afixando ::
a no final dela, por exemplo, acima Foo::->new
.
Agradeço a Ginnz no reddit por apontar isso para mim e a Toby Inkster pelo comentário (embora não tenha sentido para mim na primeira leitura).
Foo::->new
, como aprendi com o ikegami.Foo::
tem a vantagem de que avisa seFoo
não é um pacote existenteFoo->
pode-se esperar que você saiba que não existe essa sub-rotina no seu pacote. Mas se você estiver usando o Try :: Tiny e vários outros módulos cpan / outros de fontes externas, quem dirá se um deles está usando um pacote Try e, em caso afirmativo, se há um sub Tiny nele?A citação explícita do nome da classe em vez de usar uma palavra de barra (que é tratada como uma string) é uma das três maneiras de evitar a ambiguidade sintática. A seção Invocando métodos de classe da documentação do perlobj explica.
Veja este caso estranho em ação com a demonstração abaixo.
Sua saída é
O restante da seção de documentação acima mostra como se proteger contra comportamentos surpreendentes ou erros inadvertidos.
Aplicando-se à sua pergunta, todas as chamadas abaixo são equivalentes.
Anexar
::
ao final tem a vantagem de produzir um aviso útil. Digamos que você digitou acidentalmenteIsso produz
fonte