Mostrando las entradas con la etiqueta oop. Mostrar todas las entradas
Mostrando las entradas con la etiqueta oop. Mostrar todas las entradas

sábado, 4 de enero de 2014

Programacion Orientada a Objetos con Perl parte 2

Continuamos con los tutoriales de OOP de Perl,en esta ocasión vamos a tocar otro tema importante de la OOP,la herencia.

En perl la herencia se puede hacer igual que en los otros lenguajes de programación,perl maneja las clases como paquetes y para que estos hereden de otros paquetes tienes que estar relacionados entre si,las clases padre se guardan en la variable isa de UNIVERSAL,UNIVERSAL es de donde heredan todas las clases de Perl implícitamente.

Para que una clase herede de otra debemos añadirla al array ISA,pero no es necesario en estos tiempos,lo que haremos sera facilitarnos el trabajo con parent:

En perl existen muchas pero muchas formas de hacer lo mismo ya que incluso lleva el lema There's more than one way to do it,voy a intentar hacerlo de la manera mas simple posible.

Vamos a usar de ejemplo una mascota virtual,(también lo veremos en Java),creamos un archivo llamado Mascota.pm:

vim Mascota.pm

Ahora vamos a crear la clase como vimos en el tutorial pasado.

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package Mascota;

use feature 'say';

sub new 
{
    my $class = shift;
    my $self = { 
        'Hambre' => 1, 
    };
    bless $self,$class;
    return $self;
}

sub tienesHambre 
{
    my $self = shift;
    if (int($self->{Hambre}) == 1) 
    {
        say "Tengo hambre";
    } 
    else 
    {
        say "No tengo hambre";    
    }
}
sub darDeComer
{
    my $self = shift;
    $self->{Hambre} = 0;
}
1;


Como ven añadí dos funciones una por si tiene hambre y otra para quitarle el hambre(sobra explicarlo).

Ahora vamos a crear un Perro que herede esas funciones de la clase Mascota,creamos un archivo Perro.pm:

vim Perro.pm

Primero definimos el paquete:

package Perro; # Suponiendo que esta en el mismo directorio

Luego usamos Mascota como clase padre:

use parent 'Mascota';

Eso nos ahorra mucho trabajo,ya que verifica las cosas mas importantes como añadir ha isa,verificar autoherencia,etc.

Eso es todo para que un archivo heredara de otro las funciones.

Ahora lo mas importante,el constructor de la clase Perro,para que la clase Perro herede las funciones y las variables de Mascota tenemos que inicializar el constructor de Mascota,para eso creamos una clase new para perro y definimos que el self sea el self de mascota usando la palabra SUPER:


1
2
3
4
5
sub new {
    my $class = shift;
    my $self = $class->SUPER::new();
    return $self;
}

De esa manera ya estan construidos las dos clases,asi queda la clase Perro añadiendo una funcion propia de los perros:


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
package Perro;
use feature 'say';
use parent 'Mascota';

sub new {
    my $class = shift;
    my $self = $class->SUPER::new();
    return $self;
}

sub ladra {
    say 'woww';
}
1;


Ahora en el principal podemos llamar a la clase Perro y usar las funciones de mascota y de perro:


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#!/usr/bin/env perl

use strict;
use warnings;

use Perro;

my $perro = Perro->new(); # Creamos un Perro

$perro->tienesHambre(); # Le preguntamos si tiene hambre

$perro->darDeComer(); # Le damos de comer

$perro->tienesHambre(); # Le preguntamos de nuevo

$perro->ladra(); # Y ladra

Eso prueba la herencia de un archivo,veamos la herencia en otro,para eso vamos a crear la clase Gato,toda la clase sera igual solo con sus funciones únicas de un Gato:


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package Gato;
use feature 'say';
use parent 'Mascota';

sub new 
{
    my $class = shift;
    my $self = $class->SUPER::new();
    return $self;
}

sub maulla 
{
    say 'miau';
}
1;


Ahora en el programa principal podemos hacer esto:


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/env perl

use feature 'say';
use Perro;
use Gato;

my $perro = Perro->new();

$perro->tienesHambre();

$perro->darDeComer();

$perro->tienesHambre();

$perro->ladra();

my $gato = Gato->new();

$gato->maulla();

$gato->tienesHambre();



Como ven el Gato hereda las funciones y variables de Mascota,al igual que el Perro.  Tambien podemos poner todo en un mismo archivo.

Como dije en Perl se pueden hacer las cosas de muchas formas esto es un ejemplo de otra forma de herencia en Perl:

Enlace 

Mas informacion :  perldoc.perl.org
Leer más...

domingo, 29 de diciembre de 2013

Programacion Orientada a Objetos con Perl parte 1

La programación orientada a objetos en perl es un poco rara(para los que no conocen bien este lenguaje),he visto que dicen que no existe,la OOP(de ahora en adelante) en Perl es como en Lua,estamos usando tipos de datos de distintas formas en conjunto para crear un objeto,de hecho en Perl la OOP es lo mas básico que hay porque de no ser así no existirían tantos módulos de CPAN(pureperl) y vamos que CPAN es famoso por sus miles de módulos :D.

Bien,en Perl para definir una clase la podemos definir en un archivo .pm o en el mismo archivo .pl(u otra extensión),en este caso vamos a usar un archivo .pm.

Perl busca los módulos al igual que otros lenguajes,como Python,Ruby,etc primero en su PATH y luego en el directorio actual(cual sea el principio),para tener una clase que cree un objeto,vamos a crearlo en la misma carpeta:

En este caso vamos a usar dos,el principal:

vim principal.pl

Y una clase que se llame persona:

vim persona.pm

Si la clase persona.pm estuviera en un subdirectorio,por ejemplo que hiciéramos dos módulos uno para test y otro "oficial" seria así:



Bien en el modulo principal estas serian las lineas principales de siempre:


1
2
3
4
#!/usr/bin/env perl

use strict;
use warnings;

Y la clase lo añadimos asi:

use persona;

Si estuviera en test tendrías que usar cuatro puntos,ya que así es como perl ve los directorios:

use test::persona;

Bien,en la clase persona vamos a usar un constructor de clase llamado new,no necesariamente debe ser llamado new,puede ser otro nombre que no sea una palabra reservada del lenguaje,pero usare new ya que es lo que dice perldoc:

Primero que nada todo aquí son subrutinas,metodos,los cuales reciben parámetros que manipulamos con las variables especiales:

$_ y @_ o sus funciones shift,unshift

El argumento que recibiremos en la creacion de la clase sera la clase misma:

my $class = shift;

En este caso $class contendrá el nombre de persona,esto es para que sepa a que clase pertenece,ahora lo que tenemos que hacer es crear un hash para trabajar con los datos miembro:

my $self = {};

Luego debemos asociarlos de alguna manera,bless se encarga de eso:

bless $self,$class;

Ya lista la asociación devolvemos $self para que el objeto creado haga referencia a el:

return $self;

Así queda nuestro constructor:


1
2
3
4
5
6
7
sub new
{
   my $class = shift;
   my $self = {};
   bless $self,$class;
   return $self;
}

Algo muy importante es que al crear una clase nueva siempre lo primero que deben escribir es :


1
2
3
package nombre;
 # Aqui toda la clase
1;


En package tenemos que poner el nombre de la clase o paquete,debe ser el mismo del archivo(respetando mayúsculas y minúsculas) solo que sin la extensión:

1;

Es un retorno a true,que necesitan los paquetes para que funcionen,vamos a ver un poco de lo que serian set y get:


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
sub setName
{
    my $self = shift;
    $self->{NOMBRE} = shift;
}

sub getName
{
    my $self = shift;
    if ($self->{NOMBRE})
    {
        return $self->{NOMBRE};
    }
    else
    {
        return "Sin sombre";
    }
}

Cuando llamamos una función el parámetro que se nos pasa primero es el self,la referencia del hash que estamos usando,y lo demás puede ser cualquier cosa,por ejemplo en setName podemos hacer también esto:


1
2
my ($self,$n) = @_;
$self->{NOMBRE} = $n;


Bien ahora en el archivo principal vamos a crear un objeto persona:

Asi queda todo el codigo de ejemplo:


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#!/usr/bin/env perl

use warnings;
use strict;
use feature 'say';
use test::persona; # ./test/persona.pm

my $atheyus_tux = persona->new();

say $atheyus_tux->getName();

$atheyus_tux->setName("Atheyus");

say $atheyus_tux->getName();



Bien como vemos es muy sencillo,ahora vamos a ver como usar metodos internos desde la misma clase:

Gracias a bless $self esta a referencia con $class que a la vez es un shift que contiene el nombre del paquete en el ejemplo mas sencillo,pues gracias a esto $self puede usar funciones internas simplemente con llamarlas:

Por ejemplo una función que no permite  mostrar el nombre:


1
2
3
4
5
6
7
sub borraNombre {
    my $self = shift;
    if ($self->{NOMBRE}) # Si existe el nombre
    {
        $self->{NOMBRE} = "Borre el nombre"; # Cambiamos el valor
    }
}


Ahora lo podemos usar en la función getName:


1
 2
 3
 4
 5
 6
 7
 8
 9
10
sub getName {
    my $self = shift;
    $self->borraNombre(); # Lo llamamos
    if ($self->{NOMBRE}) {
        return $self->{NOMBRE};
    } else
    {
        return "Sin sombre";
    }
}


Tambien podemos crear un destructor para que destrulla las variables asociaciadas al hash:


1
2
3
4
5
sub destruye
{
   my $self=shift; #El primer parámetro de un metodo es la  clase
   delete ($self->{NOMBRE});
}


Hasta aquí la primera parte en la siguiente hablaremos de herencia,pero de momento es todo,como vemos es un ejemplo sencillo pero no se trata de eso si no de que así como es de simple el ejemplo así de simple se entienda.


Codigo completo: principal.pl

Codigo completo: persona.pm

Leer más...