Prenons un exemple plus simple
package Foo { sub new { die 7 } };
package Bar { sub new { die 42 } };
sub Foo { "Bar" }
Foo->new();
Dans l'exemple ci-dessus, la constante se Foo
résout en "Bar", donc cela n'appelle "Bar"->new
pas "Foo"->new
. Comment empêchez-vous la résolution du sous-programme? Vous pouvez le citer.
"Foo"->new();
Quant à l'implication des performances, les choses ne sont pas aggravées en utilisant une chaîne plutôt qu'un mot simple. J'ai confirmé que l'optree généré par O=Deparse
est le même. Donc, en règle générale, il semble préférable de citer les noms de classe si vous appréciez l'exactitude.
Ceci est mentionné dans Programming Perl, (malheureusement dans le contexte de l' invocation de méthode indirecte )
... nous allons donc vous dire que vous pouvez presque toujours vous en sortir avec un nom de classe nu, à condition que deux choses soient vraies. Tout d'abord, il n'y a pas de sous-programme du même nom que la classe. (Si vous suivez la convention selon laquelle les noms de sousnew
ElvenRing
- programmes comme start minuscule et les noms de classe comme start majuscule , ce n'est jamais un problème). Deuxièmement, la classe a été chargée avec l'un des
use ElvenRing;
require ElvenRing;
L'une ou l'autre de ces déclarations garantit que Perl sait qu'il ElvenRing
s'agit d'un nom de module, ce qui force tout nom nu comme new
avant le nom de classe ElvenRing
à être interprété comme un appel de méthode, même si vous avez déclaré un new
sous - programme de votre choix dans le package actuel.
Et cela a du sens: la confusion ici ne peut se produire que si vos sous-programmes (généralement en minuscules) ont le même nom qu'une classe (généralement en majuscules). Cela ne peut se produire que si vous violez la convention de dénomination ci-dessus.
tldr; c'est probablement une bonne idée de citer vos noms de classe, si vous les connaissez et que vous appréciez l'exactitude par rapport à l'encombrement.
Remarque: vous pouvez également arrêter la résolution d'un mot nu à une fonction en apposant un ::
à la fin de celle-ci, par exemple dans ce qui précède Foo::->new
.
Merci à Ginnz sur reddit de me l'avoir signalé , et à Toby Inkster pour le commentaire (même si cela n'avait pas de sens pour moi à la première lecture).
Foo::->new
, comme je l'ai appris d'ikegami.