La programmazione orientata agli oggetti in Perl non è stata introdotta subito: inizialmente, il linguaggio era procedurale. L'OOP è stata aggiunta mediante l'integrazione di strutture dinamiche basate su hash e pacchetti. Perl non utilizza la parola chiave class incorporata, come nella maggior parte degli altri linguaggi, ma opera con pacchetti e benedizione dei riferimenti.
La prima versione dell'OOP in Perl consisteva semplicemente in un pacchetto che esportava funzioni e una struttura dati (solitamente un hash), a cui veniva assegnata l'appartenenza a un pacchetto tramite la funzione bless. Successivamente, sono stati introdotti moduli CPAN come Moose/Mouse/Moo, che implementano un metaprogrammazione OOP completo (metaclassi, attributi, ruoli).
L'assenza di un unico pattern OOP porta a una diversità di stili e a incompatibilità del codice OOP tra progetti. Gli errori possono verificarsi a causa della natura dinamica del linguaggio (errori nei nomi, binding anticipato/ritardato, manipolazioni manuali del metodo bless).
Esempio di codice:
package Animal; sub new { my ($class, %args) = @_; bless { %args }, $class; } sub speak { my $self = shift; print "L'animale parla "; } package Cat; our @ISA = ('Animal'); sub speak { my $self = shift; print "Il gatto miagola "; } my $cat = Cat->new(name => 'Barsik'); $cat->speak; # Il gatto miagola
Caratteristiche chiave:
Cosa succede se in new restituisci un riferimento non bless'ed, ma solo un hash?
Restituire un riferimento non bless'ed porta al fatto che ulteriori chiamate ai metodi tramite->$obj perderanno il legame con il pacchetto e non troveranno il metodo necessario — si verificherà un errore fatale.
Come Perl gestisce l'ereditarietà multipla e la risoluzione dei conflitti di metodo?
Perl gestisce l'ereditarietà multipla: nell'array @ISA possono esserci più pacchetti. La ricerca del metodo avviene in ampiezza, da sinistra a destra, tra tutti i genitori. In caso di conflitto, verrà preso il primo metodo trovato.
È possibile "ri-benedire" (re-bless) un oggetto durante l'esecuzione, e cosa significa?
Sì, tramite bless è possibile cambiare l'appartenenza di un oggetto a un altro pacchetto durante l'esecuzione. Questo può essere usato per cambiare il "tipo" di oggetto. Tuttavia, c'è il rischio che il contenuto interno dell'oggetto non corrisponda ai nuovi metodi.
Esempio:
bless $cat, 'Dog'; # Ora $cat si comporta come un cane!
In un progetto, vengono creati oggetti tramite un array evidentemente non inizializzato, mentre i metodi si aspettano un riferimento a un hash. Il programma va in crash durante la chiamata a qualsiasi metodo, anche se la sintassi Perl consente di fare bless su qualsiasi cosa.
Vantaggi:
Svantaggi:
Utilizzo di Moose e costruttori validabili, tipizzazione rigorosa degli attributi, creazione automatica dei metodi di accesso, descrizione concisa delle relazioni tra oggetti.
Vantaggi:
Svantaggi: