Regarder Type::Tiny
, je vois que le nom de la classe dans l'appel à Type::Tiny->new
est cité dans les documents officiels,
my $NUM = "Type::Tiny"->new(
name => "Number",
constraint => sub { looks_like_number($_) },
message => sub { "$_ ain't a number" },
);
Pourquoi est-ce? Est-ce un simple style? Y a-t-il des ramifications de performances pour cette pratique?
Citer explicitement le nom de la classe plutôt que d'utiliser un mot nu (qui est traité comme une chaîne) est l'une des trois façons d'éviter l'ambiguïté syntaxique. La section Appel des méthodes de classe de la documentation perlobj explique.
Parce que Perl vous permet d'utiliser des mots nus pour les noms de packages et les noms de sous-programmes, il interprète parfois incorrectement la signification d'un mot nu. Par exemple, la construction
Class->new()
peut être interprétée comme'Class'->new()
ouClass()->new()
. En anglais, cette deuxième interprétation se lit comme "appelez un sous-programme nomméClass()
, puis appeleznew()
comme méthode sur la valeur de retour deClass()
. ” S'il existe un sous-programme nomméClass()
dans l'espace de noms courant, Perl interprétera toujoursClass->new()
comme la deuxième alternative: un appel ànew()
sur l'objet retourné par un appel àClass()
.
Voir ce cas étrange en action avec la démo ci-dessous.
#! /usr/bin/env Perl
use strict;
use warnings;
sub Type::Tiny { print "Returning Bogus\n" ; return "Bogus" }
sub Type::Tiny::new { print "Type::Tiny::new\n" }
sub Bogus::new { print "Bogus::new\n" }
my $class = "Type::Tiny";
Type::Tiny->new;
Type::Tiny::->new;
"Type::Tiny"->new;
$class->new;
Sa sortie est
Retour Bogus Bogus :: new Type :: Tiny :: new Type :: Tiny :: new Type :: Tiny :: new
Le reste de la section de documentation susmentionnée montre comment se protéger contre un comportement surprenant ou des erreurs involontaires.
Vous pouvez forcer Perl à utiliser la première interprétation ( c'est-à-dire , comme appel de méthode sur la classe nommée
"Class"
) de deux façons. Tout d'abord, vous pouvez ajouter un::
au nom de la classe:Class::->new()
Perl interprétera toujours cela comme un appel de méthode.
Alternativement, vous pouvez citer le nom de la classe:
'Class'->new()
Bien sûr, si le nom de la classe est dans un scalaire Perl fera aussi la bonne chose:
my $class = 'Class'; $class->new();
S'appliquant à votre question, tous les appels ci-dessous sont équivalents.
Type::Tiny::->new( … );
"Type::Tiny"->new( … );
my $class = "Type::Tiny";
$class->new( … );
Ajout de ::
à la fin a l'avantage de produire un avertissement utile. Dites que vous avez accidentellement tapé
Type::Tinny::->new;
Cela produit
Le mot nu "Type :: Tinny ::" fait référence à un package inexistant à la ligne ./try 15. Impossible de localiser la méthode d'objet "nouveau" via le package "Type :: Tinny" (vous avez peut-être oublié de charger "Type :: Tinny "?) À ./try ligne 15.