NOMBRE
perlootut - Manual de programación orientada a objetos en Perl
FECHA
Creado en febrero de 2011.
DESCRIPCIÓN
Este documento proporciona una introducción a la programación orientada a objetos en Perl. Comienza con una breve descripción de los conceptos relacionados con el diseño orientado a objetos. A continuación presenta varios sistemas diferentes de orientación a objetos, disponibles en CPAN, construidos sobre la base proporcionada por Perl.
El sistema de orientación a objetos predeterminado de Perl es minimalista; deja al usuario la mayor parte del trabajo. Este minimalismo tenía sentido en 1994, pero en los años que han transcurrido desde que se lanzó Perl 5.0 han surgido diversos patrones comunes en la orientación a objetos de Perl. Afortunadamente, la flexibilidad de Perl ha permitido que florezca un variado ecosistema de sistemas orientados a objetos en el lenguaje.
Si desea conocer el funcionamiento interno de la orientación a objetos en Perl, este documento explica los detalles esenciales.
Suponemos que ya conoce y comprende la sintaxis de Perl, los tipos de variables y las llamadas a subrutinas. De no ser así, lea primero perlintro. También debería leer los documentos perlsyn, perlop y perlsub.
FUNDAMENTOS DE LA ORIENTACIÓN A OBJETOS
La mayoría de los sistemas orientados a objetos comparten una serie de conceptos comunes. Probablemente ya conoce términos como "clase", "objeto", "método" y "atributo". La comprensión de estos conceptos hará más fácil la lectura y escritura de código orientado a objetos. Aunque ya esté familiarizado con estos conceptos, debería leer por encima esta sección, puesto que explica cada concepto en términos de la implementación de la orientación a objetos de Perl.
El sistema de orientación a objetos de Perl se basa en clases. La orientación a objetos basada en clases en bastante común. Se usa en Java, C++, C#, Python, Ruby y otros muchos lenguajes. Hay otros paradigmas de orientación a objetos. JavaScript es el lenguaje más popular que usa un paradigma diferente; el sistema de orientación a objetos de JavaScript se basa en prototipos.
Objeto
Un objeto es una estructura de datos que empaqueta datos y subrutinas que operan sobre los datos. Los datos de un objeto se denominan atributos y las subrutinas se denominan métodos. Un objeto puede verse como un nombre (una persona, un servicio web, un PC...).
Representa una única cosa. Por ejemplo, un objeto podría representar un archivo. Los atributos de un objeto que representa un archivo podrían incluir su ruta, el contenido y la hora de la última modificación. Si se crea un objeto para representar el archivo /etc/hostname en un equipo llamado "foo.ejemplo.com", la ruta del objeto sería "/etc/hostname", su contenido "foo\n" y la hora de la última modificación podría ser de 1304974868 segundos desde el principio del tiempo Unix.
Los métodos asociados a un archivo podrían incluir renombrar()
y escribir()
.
En Perl la mayoría de los objetos son hashes, pero los sistemas de orientación a objetos recomendados evitan tener que preocuparse de estos detalles. En la práctica es mejor considerar opaca la estructura interna de los objetos.
Clase
Una clase define el comportamiento de una categoría de objetos. Es un nombre para una categoría (como "Archivo"); también define el comportamiento de los objetos de esa categoría.
Todos los objetos pertenecen a una clase específica. Por ejemplo, nuestro objeto /etc/hostname pertenece a la clase Archivo
. Para construir un objeto específico, se comienza con la clase asociada y se construye (o se crea una instancia de) un objeto. Un objeto específico se suele llamar una instancia de la clase.
En Perl, cualquier paquete puede ser una clase. La diferencia entre un paquete que es una clase y uno que no lo es radica únicamente en cómo se utiliza. A continuación se muestra la "declaración de la clase" Archivo
:
package Archivo;
En Perl no hay una palabra reservada especial para construir un objeto. Sin embargo, la mayoría de los módulos orientados a objetos disponibles en CPAN usan el método new()
para construir un objeto nuevo:
my $nombre_host = Archivo->new(
ruta => '/etc/hostname',
contenido => "foo\n",
hora_ult_mod => 1304974868,
);
(No se preocupe por el operador ->
; se explicará más adelante).
Bendición
Como se ha indicado anteriormente, la mayoría de los objetos de Perl son hashes, pero un objeto puede ser una instancia de cualquier tipo de datos de Perl (escalar, array, etc). La conversión de una estructura de datos normal en un objeto se realiza mediante la bendición de la misma con la función bless
de Perl.
Aunque recomendamos no construir objetos partiendo de cero, debe conocer el concepto de bendición. Una estructura de datos bendecida (también conocida como "referente") es un objeto. A veces se dice que un objeto ha sido "bendecido en una clase".
Una vez que un referente ha sido bendecido, la función blessed
del módulo Scalar::Util indicará el nombre de la clase asociada. Esta subrutina devuelve la clase del objeto cuando se le pasa un objeto como argumento, y falso en cualquier otro caso.
use Scalar::Util 'blessed';
print blessed($hash); # undef
print blessed($nombre_host); # Archivo
Constructor
Un constructor crea un nuevo objeto. En Perl, el constructor de una clase es un método más; otros lenguajes de programación tienen una sintaxis especial para ellos. La mayoría de las clases Perl usan new
como nombre del constructor:
my $archivo = Archivo->new(...);
Métodos
Ya se ha indicado que un método es una subrutina que opera sobre un objeto. Se puede considerar que los métodos de un objeto son las operaciones que un objeto puede hacer. Si un objeto es un sustantivo, entonces los métodos son sus verbos (guardar, imprimir, abrir).
En Perl, los métodos no son más que subrutinas que pertenecen al paquete de una clase. Los métodos siempre se programan de forma que el primer argumento recibido sea el objeto:
sub imprimir_info {
my $self = shift;
print "Ruta del archivo: ", $self->ruta, "\n";
}
$archivo->imprimir_info;
# Ruta del archivo: /etc/hostname
Lo que hace especiales a los métodos es la forma de llamarlos. El operador flecha (->
) le indica a Perl que se está llamando a un método.
Cuando se hace la llamada a un método, Perl pasa el autor de la llamada como primer argumento. Autor de la llamada es un nombre elaborado que simplemente quiere decir lo que está a la izquierda de la flecha. El autor de la llamada puede ser un nombre de clase o un objeto. También pueden pasarse argumentos adicionales al método:
sub imprimir_info {
my $self = shift;
my $prefijo = shift // "Ruta del archivo: ";
print $prefijo, ", ", $self->ruta, "\n";
}
$file->imprimir_info("El archivo se encuentra en ");
# El archivo se encuentra en /etc/hostname
Atributos
Cada clase puede definir sus atributos. Cuando se crea una instancia de un objeto, se asignan valores a sus atributos. Por ejemplo, cada objeto de la clase Archivo
tiene su propia ruta. Los atributos también se suelen llamar propiedades.
Perl no dispone de una sintaxis especial para los atributos. Internamente, los atributos se suelen almacenar como claves del hash subyacente del objeto, pero no debe preocuparse de estos detalles.
Le recomendamos que solo acceda a los atributos a través de los métodos de acceso. Estos son métodos que permiten obtener o establecer el valor de cada atributo. Ya vimos esto antes en el ejemplo imprimir_info()
, que llama a $self->ruta
.
También puede ver los términos getter y setter. Son dos tipos de métodos de acceso. Un método getter obtiene el valor del atributo, mientras que un método setter lo establece. Un método setter también se puede llamar mutator (modificador).
Los atributos se suelen definir como de solo lectura o de lectura y escritura. Los atributos de solo lectura solo se pueden asignar al crear el objeto; los de lectura y escritura pueden modificarse en cualquier momento.
El valor de un atributo puede ser a su vez otro objeto. Por ejemplo, en lugar de devolver la hora de última modificación como un número, la clase Archivo
podría devolver un objeto de clase DateTime que representa este valor.
Es posible tener una clase donde no pueda modificarse ningún atributo. No todas las clases tienen atributos y métodos.
Polimorfismo
El polimorfismo es una forma elegante de decir que los objetos de dos clases distintas comparten una API. Por ejemplo, podríamos tener las clases Archivo
y PaginaWeb
, ambas con un método imprimir_contenido()
. Este método puede producir salidas diferentes para cada clase, pero la interfaz es común.
Las dos clases pueden ser distintas por diferentes razones, pero en lo que se refiere el método imprimir_contenido()
se comportan de la misma forma. Esto significa que podemos intentar llamar al método imprimir_contenido()
desde un objeto de cualquiera de estas clases sin saber a qué clase pertenece el objeto.
El polimorfismo es uno de los conceptos clave del diseño orientado a objetos.
Herencia
La herencia permite crear una versión especializada de una clase existente. Mediante herencia, las nuevas clases pueden reutilizar los métodos y atributos de otra clase.
Por ejemplo, podríamos crear una clase Archivo::MP3
que herede de Archivo
. Un objeto de la clase Archivo::MP3
es un (is-a) tipo de objeto más específico que un objeto de la clase Archivo
. Todos los archivos mp3 son archivos, pero no todos los archivos son archivos mp3.
A menudo se alude a las relaciones de herencia como relaciones primario-derivado o superclase/subclase
. Algunas veces se dice que la clase derivada tiene una relación de tipo "es un" (is-a en inglés) con su clase primaria.
Archivo
es una superclase de Archivo::MP3
y Archivo::MP3
es una subclase de Archivo
.
package Archivo::MP3;
use parent 'Archivo';
El módulo parent es una de las muchas formas disponibles en Perl para definir relaciones de herencia.
Perl permite la herencia múltiple: una clase puede heredar de múltiples clases primarias. Aunque esto es posible, se recomienda rotundamente no hacerlo. En general, pueden usarse roles para conseguir todo lo ofrecido por la herencia múltiple, pero de forma mucho más limpia.
No hay nada malo en definir múltiples subclases de una clase. Esto es habitual y seguro. Por ejemplo, podríamos definir las clases Archivo::MP3::VelBitsFija
y Archivo::MP3::VelBitsVariable
para distinguir entre diferentes tipos de archivos mp3.
Sobrescritura de métodos y resolución de métodos
La herencia permite que dos clases compartan código. De manera predeterminada, cada método de la clase primaria también estará disponible en la clase derivada. La clase derivada puede sobrescribir un método de la clase primaria para ofrecer su propia implementación. Por ejemplo, si tenemos un objeto de la clase Archivo::MP3
, hereda el método imprimir_info()
de la clase Archivo
:
my $minero = Archivo::MP3->new(
ruta => 'mp3/Soy-minero.mp3',
contenido => $datos_mp3,
hora_ult_mod => 1304974868,
titulo => 'Soy minero',
);
$minero->imprimir_info;
# Ruta del archivo: mp3/Soy-minero.mp3
Si deseamos incluir el título del archivo mp3 en el saludo podemos sobrescribir el método:
package Archivo::MP3;
use parent 'Archivo';
sub imprimir_info {
my $self = shift;
print "Ruta del archivo: ", $self->ruta, "\n";
print "Título: ", $self->titulo, "\n";
}
$minero->imprimir_info;
# Ruta del archivo: mp3/Soy-minero.mp3
# Título: Soy minero
El proceso de determinar qué método debe usarse se denomina resolución de métodos. Perl busca en primer lugar en la clase del objeto (Archivo::MP3
en este caso). Si la clase define el método, se llama a la versión del método en la misma. Si no, Perl busca en cada clase primaria por orden. La única clase primaria de Archivo::MP3
es Archivo
. Si la clase Archivo::MP3
no define el método, pero sí lo hace la clase Archivo
, entonces Perl llamará al método de la clase Archivo
.
Si Archivo
hereda de OrigenDatos
, que hereda a su vez de Cosa
, entonces Perl deberá subir siguiendo la cadena, si es necesario.
Es posible llamar explícitamente a un método de la clase primaria desde una clase derivada:
package Archivo::MP3;
use parent 'Archivo';
sub imprimir_info {
my $self = shift;
$self->SUPER::imprimir_info();
print "Título: ", $self->titulo, "\n";
}
SUPER::
le indica a Perl que busque el método imprimir_info()
en la cadena de herencia de la clase Archivo::MP3
. Cuando encuentra la clase primaria que implementa este método, llama al método.
Antes mencionamos la herencia múltiple. El problema de la herencia múltiple es que complica enormemente la resolución de métodos. Consulte perlobj para obtener más información.
Encapsulación
La encapsulación expresa la idea de que los objetos son opacos. Cuando otros desarrolladores usen su clase no necesitarán saber cómo se ha implementado; solo tienen que saber qué es lo que hace.
La encapsulación es importante por varias razones. En primer lugar, permite separar la API pública de la implementación privada. Esto significa que se puede cambiar la implementación sin cambiar la API.
En segundo lugar, cuando las clases están bien encapsuladas se hace más fácil la creación de subclases. Idealmente, una subclase usa las mismas API para acceder a los datos del objeto que las usadas por la clase primaria. En realidad, a veces la creación de subclases requiere infringir el principio de encapsulación, pero si la interfaz es buena, la posibilidad de que esto ocurra es mínima.
Ya se ha mencionado previamente que la mayoría de los objetos Perl se implementan internamente como hashes. El principio de encapsulación nos dice que no deberíamos basarnos en esta característica. En lugar de esto, deberíamos usar métodos de acceso para acceder a los datos del hash. Los sistemas de orientación a objetos que se recomiendan a continuación automatizan la generación de los métodos de acceso. Si usa cualquiera de ellos, no tendrá que acceder directamente al hash.
Composición
Es habitual en el código orientado a objetos que un objeto contenga referencias a otro objeto. Esto se denomina composición, o relación "tiene-un" (has-a en inglés).
Se ha mencionado previamente que en la clase Archivo
el método de acceso al miembro hora_ult_mod
podría devolver un objeto de la clase DateTime. Este es un ejemplo perfecto de composición. Incluso se puede hacer que los métodos de acceso a ruta
y contenido
devuelvan también objetos. La clase Archivo
estaría compuesta de varios objetos.
Roles
Los roles representan lo que la clase hace, no lo que la clase es. Son relativamente recientes en Perl, pero su uso se ha popularizado. Los roles se aplican a las clases. Se puede decir que las clases consumen roles.
Los roles son una alternativa a la herencia para ofrecer polimorfismo. Supongamos que tenemos dos clases: Radio
y Equipo
. Ambos aparatos tienen interruptores de encendido/apagado. Queremos expresar esto en las definiciones de las clases.
Podríamos hacer que ambas clases heredasen de una clase primaria común, como Máquina
, aunque no todas las máquinas disponen de estos interruptores. Podríamos crear una clase primaria llamada TieneInterruptor
, pero sería algo muy artificial. Las radios y los equipos no son casos especiales de esta clase primaria. De hecho, esta clase primaria es más bien ridícula.
Aquí es donde entran en juego los roles. Tiene sentido crear un rol TieneInterruptor
y aplicarlo a ambas clases. Este rol podría definir una interfaz conocida con los métodos encender()
y apagar()
.
Perl no dispone de ningún mecanismo para expresar roles. En el pasado, los programadores tenían que resignarse a usar herencia múltiple. Actualmente ya existen varias opciones buenas en CPAN para usar roles.
Cuándo se debe usar la orientación a objetos
La orientación a objetos no es la mejor solución para todos los problemas. En el libro Perl Best Practices (publicado en 2004 por O'Reilly Media, Inc.), Damian Conway proporciona una lista de criterios para decidir si la orientación a objetos se ajusta a nuestro problema:
El sistema que se está diseñando es grande o puede llegar a serlo.
Los datos se pueden agregar en estructuras obvias, especialmente si hay una gran cantidad de datos en cada agregado.
Los distintos tipos de datos agregados forman una jerarquía natural que facilita el uso de la herencia y el polimorfismo.
Tiene datos a los que hay que aplicar muchas operaciones diferentes.
Es necesario llevar a cabo las mismas operaciones generales sobre tipos de datos relacionados, pero con ligeras variaciones en función del tipo de datos específico al que se aplican estas operaciones.
Es probable que tenga que agregar nuevos tipos de datos más adelante.
Las interacciones típicas entre elementos de datos se representan mejor mediante operadores.
Es probable que la implementación de componentes individuales del sistema cambie con el tiempo.
El diseño del sistema ya es orientado a objetos.
Muchos programadores van a utilizar sus módulos de código.
SISTEMAS ORIENTADOS A OBJETOS EN PERL
Como ya se ha mencionado antes, el sistema de orientación a objetos de Perl es minimalista, pero también muy flexible. A lo largo de los años, muchas personas han desarrollado sistemas basados en el sistema predefinido de Perl para proporcionar más características y facilidades.
Le recomendamos que use alguno de los sistemas siguientes. Incluso los más sencillos le ahorrarán tener que escribir el mismo código repetidamente. No hay ninguna razón para empezar a escribir clases desde cero.
Si está interesado en conocer los detalles de estos sistemas, consulte perlobj.
Moose
Moose se presenta como un "sistema postmoderno de orientación a objetos para Perl 5". No se asuste, la etiqueta "postmoderno" es una referencia a la descripción de Perl que hizo Larry: "el primer lenguaje de programación postmoderno".
Moose
proporciona un completo y moderno sistema de orientación a objetos. Su principal influencia es el sistema de orientación a objetos de Common Lisp, pero también toma ideas de Smalltalk y de otros lenguajes. Moose
fue creado por Stevan Little y se basa en su trabajo sobre el diseño de orientación a objetos de Perl 6.
El código de nuestra clase Archivo
con Moose
sería:
package Archivo;
use Moose;
has ruta => ( is => 'ro' );
has contenido => ( is => 'ro' );
has hora_ult_mod => ( is => 'ro' );
sub imprimir_info {
my $self = shift;
print "Ruta del archivo: ", $self->ruta, "\n";
}
Moose
proporciona diversas características:
Simplificación declarativa
Moose
proporciona una capa de simplificación declarativa para definir las clases. Esta simplificación consiste en un conjunto de funciones exportadas que hacen que la declaración de las clases sea más sencilla y agradable. Esto permite describir qué es la clase, en lugar de tener que decir a Perl cómo implementar la clase.Los atributos se declaran con la subrutina
has()
yMoose
crea automáticamente los métodos de acceso para los atributos declarados. También se ocupa de crear automáticamente un métodonew()
. Este constructor sabe cuáles son los atributos declarados, por lo que puede establecerlos al crear una nueva instancia deArchivo
.Roles predefinidos
Moose
permite definir roles de la misma forma en que se definen las clases:package TieneInterruptor; use Moose::Role; has encendido => ( is => 'rw', isa => 'Bool', ); sub encender { my $self = shift; $self->encendido(1); } sub apagar { my $self = shift; $self->encendido(0); }
Un sistema de tipos en miniatura
En el ejemplo anterior se aprecia que se pasa un valor
isa => 'Bool'
ahas()
al crear el atributoencendido
. Esto le dice aMoose
que este atributo debe ser un valor booleano. Si se intenta asignar un valor no válido el código generará un error.Introspección completa y manipulación
Las características de introspección predefinidas son mínimas.
Moose
se basa en ellas y crea una capa completa de introspección para sus clases. Esto permite contestar a preguntas como "¿qué métodos implementa la clase Archivo?". También permite modificar las clases mediante programación.Autocontenido y extensible
Moose
se describe a sí mismo mediante su propia API de introspección. Además de ser un truco ingenioso, significa que puede extenderMoose
medianteMoose
.Ecosistema variado
Existe un variado ecosistema de extensiones de
Moose
en CPAN, en el espacio de nombres MooseX. Además, muchos módulos de CPAN ya usanMoose
, lo que proporciona muchos ejemplos de los que puede aprender.Muchas más características
Moose
es una herramienta muy poderosa. Aquí solo hemos descrito una pequeña parte de sus características. Le animamos a aprender más mediante la lectura de la documentación deMoose
, comenzando con Moose::Manual.
Por supuesto, Moose
no es perfecto.
Puede hacer que su código tarde más tiempo en cargar. Moose
no es pequeño y genera una gran cantidad de código cuando el usuario define sus propias clases. Esto hace que el código en tiempo de ejecución sea lo más eficiente posible, pero tendrá un coste cuando todo este código se cargue por primera vez.
Este incremento en el tiempo de carga puede ser problemático cuando la velocidad de inicio es importante, como en scripts de línea de comandos o en el típico script CGI que debe cargarse cada vez que se ejecuta.
Antes de asustarse debe saber que mucha gente usa Moose
para construir herramientas de línea de comandos y código con necesidades específicas de tiempo de inicio. Le animamos a probar Moose
antes de preocuparse por la velocidad de inicio.
Por otra parte, Moose
depende de muchos módulos. La mayoría son módulos independientes, algunos generados a partir de Moose
. Moose
y algunas de sus dependencias requieren un compilador. Si tiene que instalar el software en un sistema sin compilador, o si las dependencias suponen un problema, entonces Moose
podría no ser la solución adecuada.
Mouse
Si prueba Moose
y encuentra que algunas de estas características impiden su uso, le recomendamos entonces el uso de Mouse. Mouse
implementa un subconjunto de la funcionalidad de Moose
en un paquete más simple. La interfaz final es la misma para todas las características que implementa, de forma que es posible cambiar de Mouse
a Moose
de forma sencilla.
Mouse
no implementa la mayor parte de la interfaz de introspección de Moose
, por lo que la carga de módulos resulta más rápida. Además, todas las dependencias necesarias están incluidas en el núcleo de Perl, de forma que puede ejecutarse sin necesidad de compilador. Si dispone de compilador, Mouse
lo usará para compilar parte de su código o bien para aumentar la velocidad.
Por último, incluye el módulo Mouse::Tiny
, que consta de la mayoría de las características de Mouse
y que se empaqueta en un único archivo de módulo. Puede copiar este archivo de módulo en el directorio de bibliotecas de la aplicación para facilitar su empaquetamiento.
Los autores de Moose
esperan que algún día, cuando Moose
haya mejorado lo suficiente, Mouse
pueda quedar obsoleto, pero de momento proporciona una sólida alternativa a Moose
.
Class::Accessor
Class::Accessor es el polo opuesto a Moose
. Proporciona muy pocas características y no es autocontenido.
Sin embargo, es muy simple, está programado en Perl puro y no tiene ninguna dependencia externa al núcleo. También proporciona una API "de tipo Moose" para las características que ofrece.
Aunque no le quitará mucho trabajo, es preferible a escribir sus propias clases desde cero.
La clase Archivo
con Class::Accessor
sería:
package Archivo;
use Class::Accessor 'antlers';
has ruta => ( is => 'ro' );
has contenido => ( is => 'ro' );
has hora_ult_mod => ( is => 'ro' );
sub imprimir_info {
my $self = shift;
print "Ruta del archivo: ", $self->ruta, "\n";
}
La marca de importación antlers
indica a la clase Class::Accessor
que desea definir los atributos con el estilo de sintaxis de Moose
. El único parámetro que puede pasar a has
es is
. Le recomendamos el uso del estilo de sintaxis de Moose si elige Class::Accessor
, ya que así le resultará más sencillo el trabajo de migración si posteriormente decide usar Moose
.
Al igual que Moose
, Class::Accessor
genera los métodos de acceso y un constructor para la clase.
Object::Tiny
Por último, también puede usar Object::Tiny. Este módulo se ajusta realmente a su nombre. Tiene una interfaz de programación realmente mínima y carece de dependencias (del núcleo o externas). Sin embargo, es mucho más sencillo usar este módulo que escribir código orientado a objetos desde cero.
Nuestra clase Archivo
sería:
package Archivo;
use Object::Tiny qw( ruta contenido hora_ult_mod );
sub imprimir_info {
my $self = shift;
print "Ruta del archivo: ", $self->ruta, "\n";
}
¡Y ya está!
Con Object::Tiny
todos los métodos de acceso son de solo lectura. También genera automáticamente un constructor y todos los métodos de acceso que defina.
Role::Tiny
Como se mencionó con anterioridad, los roles proporcionan un alternativa a la herencia, pero Perl no ofrece esta característica de forma predefinida. Si elige usar Moose, dispondrá de una implementación completa de los roles. Si usa alguno de los otros módulos de orientación a objetos recomendados, también podrá usar roles con Role::Tiny
Role::Tiny
ofrece algunas de las características que proporciona el sistema Moose, pero en un paquete mucho más pequeño. En particular, no admite ningún tipo de declaración de atributo, por lo que tendrá que declararlos a mano. Aun así es útil y funciona bien con Class::Accessor
y Object::Tiny
Resumen de sistemas de orientación a objetos
A continuación se ofrece un breve resumen de las opciones consideradas:
-
Moose
es la opción máxima (la más completa). Dispone de muchas características, un gran ecosistema y una importante base de usuarios. También se ha descrito brevemente Mouse.Mouse
es una versión reducida deMoose
que ofrece una alternativa razonable cuando Moose no es adecuado para su aplicación. -
Class::Accessor
es un sistema mucho más reducido queMoose
, pero ofrece una alternativa interesante cuandoMoose
resulta excesivo. Se ha utilizado durante mucho tiempo y está bien probado. También ofrece un modo de compatibilidad mínima conMoose
que facilita la migración desdeClass::Accessor
aMoose
. -
Object::Tiny
es la opción más minimalista. No presenta dependencias y casi no hay sintaxis que aprender. Es una buena opción para entornos reducidos y para crear un programa rápidamente sin preocuparse de los detalles. -
Use
Role::Tiny
conObject::Tiny
oClass::Accessor
si desea usar herencia múltiple. Si se decanta porMoose
, podrá disponer de su implementación de roles.
Otros sistemas de orientación a objetos
En CPAN encontrará decenas de módulos relacionados con la orientación a objetos, además de los considerados aquí; es posible que se encuentre con varias de estas alternativas si trabaja con código de otras personas.
Además, existe mucho código en el que se usa orientación a objetos "a mano", basado en las características de orientación a objetos predefinidas de Perl. Si necesita mantener este tipo de código, debería leer perlobj para comprender exactamente cómo funciona la orientación a objetos ofrecida por Perl.
CONCLUSIÓN
Como se indicó con anterioridad, el sistema de orientación a objetos de Perl es minimalista y esto ha hecho que surgieran muchos sistemas de programación orientada a objetos en CPAN. Aunque puede prescindir de estos sistemas modernos y escribir sus propias clases a mano, no es necesario hacerlo con las versiones modernas de Perl.
Para sistemas pequeños, tanto Object::Tiny como Class::Accessor ofrecen sistemas minimalistas que se ocupan de las tareas repetitivas y simplifican el trabajo.
Para proyectos más complejos, Moose proporciona un variado conjunto de características que le permitirán centrarse en la implementación de la lógica del sistema.
Le recomendamos que pruebe Moose, Class::Accessor y Object::Tiny para decidir qué sistema de orientación a objetos le conviene más.
TRADUCTORES
Manuel Gómez Olmedo
Joaquín Ferrero (Tech Lead)
Enrique Nell (Language Lead)