Citare esplicitamente il nome della classe piuttosto che usare una parola nuda (che viene trattata come una stringa) è uno dei tre modi per evitare l'ambiguità sintattica. La sezione Metodi di classe invocanti della documentazione di perlobj spiega.
Poiché Perl consente di utilizzare le password per i nomi dei pacchetti e dei sottoprogrammi, a volte interpreta il significato di una parola non corretta. Ad esempio, il costrutto Class->new()
può essere interpretato come uno 'Class'->new()
o Class()->new()
. In inglese, quella seconda interpretazione si legge come "chiama una subroutine denominata Class()
, quindi chiama new()
come metodo sul valore restituito di Class()
". Se esiste una subroutine denominata Class()
nello spazio dei nomi corrente, Perl interpreterà sempre Class->new()
come la seconda alternativa: una chiamata a
new()
sull'oggetto restituita da una chiamata a Class()
.
Guarda questo strano caso in azione con la demo di seguito.
#! /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;
Il suo output è
Ritorno fasullo
Bogus :: new
Tipo :: :: Piccolo nuova
Tipo :: :: Piccolo nuova
Tipo :: :: Piccolo nuova
Il resto della sezione di documentazione sopra menzionata mostra come proteggere da comportamenti sorprendenti o errori involontari.
È possibile forzare Perl a utilizzare la prima interpretazione ( ovvero , come una chiamata di metodo sulla classe denominata "Class"
) in due modi. Innanzitutto, puoi aggiungere ::
a al nome della classe:
Class::->new()
Perl interpreterà sempre questo come una chiamata di metodo.
In alternativa, puoi citare il nome della classe:
'Class'->new()
Naturalmente, se il nome della classe è in uno scalare, Perl farà anche la cosa giusta:
my $class = 'Class';
$class->new();
Applicando alla tua domanda, tutte le chiamate sotto sono equivalenti.
Type::Tiny::->new( … );
"Type::Tiny"->new( … );
my $class = "Type::Tiny";
$class->new( … );
L'aggiunta ::
alla fine ha il vantaggio di produrre un avviso utile. Di 'che hai digitato per errore
Type::Tinny::->new;
Questo produce
La parola nuda "Tipo :: Tinny ::" si riferisce al pacchetto inesistente alla riga ./try 15.
Impossibile trovare il metodo oggetto "nuovo" tramite il pacchetto "Tipo :: Tinny" (forse hai dimenticato di caricare "Tipo :: Tinny"?) Alla riga ./try 15.
Foo::->new
, come ho imparato da Ikegami.