2012-06-13 18 views
5

Non riesco a capire una spiegazione su come il polimorfismo funzioni in Perl. Capisco cosa significa polimorfismo, ma sto cercando di capire come funziona internamente all'interno di Perl. Qualcuno può indicarmi una documentazione che la spieghi. Tutte le ricerche di google che ho fatto mi forniscono esempi di ciò che il polimorfismo è in Perl, ma non come perl lo fa funzionare.Come funziona il polimorfismo Perl?

+0

Implementazione interna o sintassi/utilizzo? – djechlin

risposta

14

Quando un method is invoked su un oggetto o una classe, Perl cerca di vedere se quel metodo è fornito direttamente dalla classe stessa.

Perché classes are simply Perl packages, si tratta semplicemente di cercare l'esistenza di una subroutine &Class::method.

Se non viene trovata tale subroutine, Perl esamina la matrice @ISA nello stesso pacchetto (cioè @Class::ISA), che contiene un elenco di classi base per la classe, e fa lo stesso controllo per ogni pacchetto/classe che appare in là.

Ciascuna di queste classi può anche avere una matrice @ISA, quindi la ricerca è ricorsiva.

Infine, se il metodo non viene trovato da nessuna parte con questo metodo, Perl cerca in un pacchetto speciale UNIVERSAL per una subroutine &UNIVERSAL::method.

Un errore a questo punto continua a richiamare il sistema AUTOLOAD, ma questo è davvero oltre il principio del polimorfismo.

L'impossibilità di trovare un metodo di abbinamento adatto ovunque solleva un'eccezione.

0

Questo si adatta bene al polimorfismo basato sull'eredità e dà un'idea di ciò che Perl fa specificamente. Ho sempre usato il capitolo 12.5. Ereditarietà classe in Programming Perl come riferimento per queste cose.

+0

per Perl OOP, mi è sempre piaciuto "Learning Perl Objects, References and Modules" di O'Reilly: http://shop.oreilly.com/product/9780596004781.do – David

7

Capitolo 7 da Object Oriented Perl, Damian Conway, Manning (2000) si chiama Polimorfismo. Dieci pagine.

Si consiglia, tuttavia, se si proviene da C++ o Java o C# o simili, che non c'è molto da sapere sul "polimorfismo" in Perl. Direi anche che il concetto di polimorfismo rende le cose più complicate di quanto non lo siano in Perl.

Penso che il meccanismo che un programmatore Perl dovrebbe sforzarsi di capire è come funziona la ricerca dei metodi. La risposta è: scansione ricorsiva in profondità prima attraverso gli array di pacchetti @ISA.

Un esempio, facciamo $o->bla. Il nostro $o è benedetto nel pacchetto A, che non ha un'implementazione di bla. Ma eredita dal primo B e poi dallo C (@ISA = ('B', 'C')). Diamo prima una ricerca a B. Neanche definisce il metodo. Se avesse classi genitore, continueremmo la nostra ricerca lì. Ma non è così. Quindi ora esaminiamo C e fortunatamente ha il metodo, altrimenti sarebbe un errore di runtime, perché il pacchetto di ultima istanza, UNIVERSAL, non definisce neanche bla.

4

Un metodo chiamata oggetto è fondamentalmente una versione ottimizzata * delle seguenti operazioni:

my $class = ref($_[0]); 
my @isa = mro::get_linear_isa($class); 
for my $pkg (@isa) { 
    if (exists(&{$pkg.'::'.$method_name})) { 
     return &{$pkg.'::'.$method_name}; 
    } 
} 

ref ottiene il nome della classe associato all'oggetto. La classe è memorizzata nella variabile dell'oggetto.

$ perl -MDevel::Peek -e'my $o = {}; Dump($o); bless($o, "SomeClass"); Dump($o);' 
SV = IV(0x9e4ae0c) at 0x9e4ae10 
    REFCNT = 1 
    FLAGS = (PADMY,ROK) 
    RV = 0x9e317d0 
    SV = PVHV(0x9e36808) at 0x9e317d0 
    REFCNT = 1 
    FLAGS = (SHAREKEYS) 
    ARRAY = 0x0 
    KEYS = 0 
    FILL = 0 
    MAX = 7 
    RITER = -1 
    EITER = 0x0 
SV = IV(0x9e4ae0c) at 0x9e4ae10 
    REFCNT = 1 
    FLAGS = (PADMY,ROK) 
    RV = 0x9e317d0 
    SV = PVHV(0x9e36808) at 0x9e317d0 
    REFCNT = 1 
    FLAGS = (OBJECT,SHAREKEYS)  <---- 
    STASH = 0x9e323d0 "SomeClass" <---- 
    ARRAY = 0x0 
    KEYS = 0 
    FILL = 0 
    MAX = 7 
    RITER = -1 
    EITER = 0x0 

get_linear_isa si basa sulla @ISA in pacchetto $class, e la @ISA dei pacchetti in esso citati.

Poiché il nome della classe è nell'oggetto e poiché Perl può controllare la sua tabella dei simboli in fase di esecuzione, non è necessaria una tabella del metodo virtuale per fornire il polimorfismo.

* — Memorizza nella cache quale pacchetto fornisce il metodo $ nome_metodo per la classe $ classe. Inoltre, sicuramente non calcola l'intero ISA lineare in anticipo, ma se necessario.

1

Il polimorfismo è semplicemente l'idea che oggetti di tipi diversi rispondano a chiamate di metodo con lo stesso nome. Linguaggi deboli tipizzati, come Perl, sono "implicitamente polimorfi".

Ad esempio, un oggetto CGI, un oggetto Apache2::Request, e un oggetto Plack::Request hanno tutti un metodo param che restituirà i parametri di una richiesta HTTP. Potrei scrivere una funzione che accetta un oggetto come parametro e chiamare il metodo param su quell'oggetto e ottenere un parametro di richiesta HTTP, senza sapere quale tipo di oggetto sia.

Le lingue fortemente tipizzate non funzionano in questo modo perché le loro funzioni specificano i tipi di dati dei loro parametri. Non riesco a chiamare una funzione in Java con un oggetto di tipo Dog se si aspettava uno di Cat. Quindi i linguaggi fortemente tipizzati devono creare meccanismi speciali per consentire il polimorfismo.

Problemi correlati