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

No hay comentarios.:

Publicar un comentario

Los comentarios serán revisados antes de ser publicados.