Curso de Perl
Perl logo
Contenido
Indice
Capítulo 1
Capítulo 2
Capítulo 3
Capítulo 4
Capítulo 5
Tareas 1
Tareas 2
Tareas 3
Tareas 4
Tareas 5
Elaborado por
Red Antigua Logo
Capítulo 5: Clases y objetos.

Capítulo 1

Tareas 1
Capítulo 2

Tareas 2
Capítulo 3

Tareas 3
Capítulo 4

Tareas 4
Capítulo 5

Tareas 5
Capítulo 5: Clases y objetos.        
Terminología

Paso por paso
Clases vs. Librerias

Herencia
Un objeto de Perl - bless



Este capítulo se enfoca a diseño general de clases y objetos.


 
Terminología: (arriba)
En Perl la terminología de Object-Oriented (OO) programming se aplica de la siguiente manera:
  • Un objeto es un variable que pertenece a una clase.
  • Métodos son funciones asociadas a objetos o clases.
  • Propiedades de instancia son propiedades que afectan sólo el objeto.
  • Propiedades de clase son propiedades que afectan a todos los objetos de esta clase.
  • Una clase es un Package, y normalmente un módulo, o sea un archivo .pm.
  • El objeto (o variable) es una referencia que se ha aplicado la función bless.
 
Clases vs. Librerias: Similaridades y diferencias: (arriba)
Las dos se almacenan en un archivo .pm.

Una clase es un conjunto de métodos (subrutinas), pero especialmente un método normalmente (pero no necesariamente) llamado new(), que crea un objeto.
A través de este objeto se puede accessar los demás métodos.
Además, un objeto cuenta con propiedades, que se pueden modificar a traves de métodos.
Esto permite a un objeto llevar distintos estados durante la ejecución de un programa.

Una libreria es un conjunto de funciones (subrutinas) con algo en común (por eso se almacenan en el mismo archivo), que se pueden ejecutar desde un programa, pero estas funciones no llevan un estado (como lo hace un objeto), solo devuelve uno o varios valores.

 
Un objeto de Perl - una referencia con bless: (arriba)
Un objeto se crea con la función bless, argumento la referencia (ver perldoc -f bless por detalles).
En teoría, la referencia puede referirse a cualquier tipo de variable, pero en la práctica siempre se refiere a un hash vacío.
Unas formas de crear un objeto:
  1. Este ejemplo sólo sirve para mostrar lo que es un objeto.
    my %hash;
    my $hash_ref = \%hash;
    my $blessed_hash_ref = bless $hash_ref;
    my $object = $blessed_hash_ref;
    

    El output de print "$hash_ref\n$object\n";
    HASH(0x804ef00)
    main=HASH(0x804ef00)
    			      
    muestra que $hash_ref apunta a un hash, mientras $object apunta al mismo hash, pero en el namespace main (namespace actual, como usamos bless con sólo un argumento).

  2. Una referencia a un hash vacío se puede escribir como {}, que facilita la creación de un objeto:my $object = bless {};
  3. Normalmente se crea un objeto a través de una función, normalmente llamado new:
    # Crear el objeto
    sub new {
        my $class = shift;
        return bless {}, $class;
    }
    			      
    La forma de llamar la función (si la función new está definido en el namespace principal, main):
    my $object = main->new();
    			      
    Sin embargo, normalmente se define la clase en un módulo, o sea en un archivo .pm.
    Supongamos que la clase Some::Class está definida en Some/Class.pm, y que contiene el método new descrito arriba.
    Como se ve en la definición de new, el argumento es el nombre de la clase.
    Esto nos permite llamar new en dos formas:
    my $object = Some::Class->new();
    
    o bien:
    my $object = new Some::Class;
    

  4. Pero un objeto es aburrido sin métodos y propiedades, pero son faciles de crear dentro de la clase.
    Todos los subs dentro de Some/Class.pm sirven como un métodos, y los subs que modifica/devuelve un valor del hash del objeto sirven como propiedades. Un ejemplo de agregar un método y una propiedad al archivo Some/Class.pm:
    sub un_metodo {print "Hola!\n"};
    sub una_propiedad {
        my $object = shift;
        $object->{PROPIEDAD} = shift if @_;
        return $object->{PROPIEDAD};
    }
    			      
    Como accesar los métodos y las propiedades desde un programa:
    #!/usr/bin/perl -w
    use strict;
    use Some::Class;
    my $object = Some::Class->new();			      
    # Accesar un metodo
    $object->un_metodo;
    # Accesar una propiedad siempre se debe hacer a traves de un metodo
    # Propiedad - set
    $object->una_propiedad(123);
    # Propiedad - get
    print $object->una_propiedad(),"\n";
    
    			      
    Nota que es posible accesar el valor del hash (en este ejemplo $object->{PROPIEDAD}) directamente en vez de usar el método una_propiedad para hacerlo, pero es mala costumbre y mala programación.
    En otra versión del módulo Some::Class el método una_propiedad puede contener funcionalidad agregada que debe ser transparente al usuario de Some::Class.
    La documentación del módulo debe indicar que métodos se deben usar.
 
Crear un módulo OO - paso por paso: (arriba)
Vamos a crear un módulo My/Person.pm para crear en objeto $persona de la clase My::Person.
  1. En el directorio actual, crear la plantilla para el módulo con h2xs -XA -n My::Person
  2. La interface de un módulo OO es más sencillo de crear que la interface de un módulo tipo librería (ver capítulo 4)
    porque no vamos a exportar ningún método, todos los métodos y propiedades se accesan a través del objeto.
    package My::Person;
    
    use strict;
    use vars qw($VERSION @ISA);
    
    # '@ISA = qw()' se lee como
    # este modulo 'is a nothing'
    # no importa nada de otros modulos
    @ISA = qw();
    
    $VERSION = '0.01';
    
    # Preloaded methods go here.
    
    # Crear el objeto
    sub new {
        my $class = shift;
        return bless {}, $class;
    }
    
    # Nombre de la persona
    sub nombre {
        my $self = shift;
        $self->{NAME} = shift if @_;
        return $self->{NAME};
    }
    
    # Edad de la persona
    sub edad {
        my $self = shift;
        $self->{EDAD} = shift if @_;
        return $self->{EDAD};
    }
    
    # La ultima linea siempre debe devolver True			      
    1;
    			      
  3. Hacer un symbolic link para poder accesar nuestro módulo desde el directorio actual,
    mientras lo estamos desarrollando, sin instalar el módulo formalmente:

    cd My; ln -s Person/Person.pm; cd..

  4. En el directorio actual, crear el script myperson.pl:
    #!/usr/bin/perl -w
    use strict;
    use My::Person;
    my $persona = My::Person->new();
    $persona->edad(11);
    $persona->nombre('Julio');
    my $persona2 = My::Person->new();
    $persona2->edad(22);
    $persona2->nombre('Maria');
    print $persona->edad(),"\n";
    print $persona2->edad(),"\n";
    print $persona->nombre(),"\n";
    print $persona2->nombre(),"\n";
    			      
 
Herencia de clases: (arriba)
El siguiente ejemplo muestra como reusar código de la clase My::Person para extender la funcionalidad con el módulo My::Employee.
Vamos a agregar el método puesto.
  1. En el directorio actual:

    h2xs -XA -n My::Employee

  2. Modificar My/Employee/Employee.pm:
    package My::Employee;
    use strict;
    use vars qw($VERSION @ISA);
    use My::Person;
    
    # '@ISA = qw(My::Person)' se lee como			      
    # este modulo 'is a My::Person',
    # o sea, usa metodos del modulo My::Person
    @ISA = qw(My::Person);
    			      
    $VERSION = '0.01';
    
    # Preloaded methods go here.
    
    # Puesto del empleado
    sub puesto {
        my $self = shift;
        $self->{ROLE} = shift if @_;
        return $self->{ROLE};
    }
    
    1;
    
    
  3. Hacer un symbolic link:

    cd My; ln -s Employee/Employee.pm; cd..

  4. En el directorio actual, crear el script myemployee.pl:
    #!/usr/bin/perl -w
    use strict;
    use My::Employee;
    my $empleado = My::Employee->new();
    my $empleado2 = My::Employee->new();
    $empleado->edad(11);
    $empleado->nombre('Julio');
    $empleado->puesto('tecnico');
    $empleado2->edad(22);
    $empleado2->nombre('Maria');
    $empleado2->puesto('secretaria');
    print $empleado->edad(),"\n";
    print $empleado2->edad(),"\n";
    print $empleado->nombre(),"\n";
    print $empleado2->nombre(),"\n";
    print $empleado->puesto(),"\n";
    print $empleado2->puesto(),"\n";
    
    			      
  5. Como se nota, un $empleado herede todas las características de una $persona, además cuenta con un puesto().
  • Tareas:
    1. Leer perldoc pertoot.
    2. Leer perldoc perbot.

Last modified: Sat Apr 24 14:52:09 CST 2004