Perl Orientado a Objetos
## Objetivos de Aprendizaje
- Comprender bless y referencias
- Crear clases con bless
- Usar herencia
- Comprender el despacho de metodos
- Introduccion a Moose
## Conceptos Basicos
### Que es OOP?
- **Objetos**: Instancias de clases
- **Clases**: Planos para objetos
- **Metodos**: Funciones que operan sobre objetos
- **Propiedades/Atributos**: Datos almacenados en objetos
### Modelo OOP de Perl
```perl
package MiClase;
sub new {
my ($class, %args) = @_;
my $self = bless \%args, $class;
return $self;
}
sub metodo {
my ($self, @args) = @_;
# Implementacion
}
```
## Funcion bless
### Creando Objetos
```perl
package Persona;
use strict;
use warnings;
sub new {
my ($class, %args) = @_;
my $self = bless {
nombre => $args{nombre} // "Anonimo",
edad => $args{edad} // 0,
}, $class;
return $self;
}
1;
```
### Usando el Objeto
```perl
use strict;
use warnings;
use Persona;
my $persona = Persona->new(nombre => "Alice", edad => 30);
print $persona->{nombre}; # Acceso directo (no recomendado)
print $persona->{edad};
```
## Metodos
### Metodos de Instancia
```perl
package Persona;
use strict;
use warnings;
sub new {
my ($class, %args) = @_;
return bless \%args, $class;
}
sub saludar {
my ($self) = @_;
return "Hola, mi nombre es $self->{nombre}";
}
sub cumplir_anos {
my ($self) = @_;
$self->{edad}++;
return $self->{edad};
}
1;
```
```perl
use strict;
use warnings;
use Persona;
my $persona = Persona->new(nombre => "Alice", edad => 30);
print $persona->saludar(); # "Hola, mi nombre es Alice"
print $persona->cumplir_anos(); # 31
```
### Metodos de Clase
```perl
package Persona;
use strict;
use warnings;
sub new {
my ($class, %args) = @_;
return bless \%args, $class;
}
sub crear_predeterminado {
my ($class) = @_;
return $class->new(nombre => "Predeterminado", edad => 0);
}
1;
```
```perl
use strict;
use warnings;
use Persona;
my $persona = Persona->crear_predeterminado();
```
## Accessors
### Accessor Simple
```perl
package Persona;
use strict;
use warnings;
sub new {
my ($class, %args) = @_;
return bless \%args, $class;
}
sub nombre {
my $self = shift;
if (@_) {
$self->{nombre} = shift;
}
return $self->{nombre};
}
sub edad {
my $self = shift;
if (@_) {
$self->{edad} = shift;
}
return $self->{edad};
}
1;
```
### Usando Accessors
```perl
use strict;
use warnings;
use Persona;
my $persona = Persona->new(nombre => "Alice", edad => 30);
print $persona->nombre(); # "Alice"
$persona->nombre("Bob");
print $persona->nombre(); # "Bob"
```
## Herencia
### @ISA y Herencia
```perl
package Animal;
use strict;
use warnings;
sub new {
my ($class, %args) = @_;
return bless \%args, $class;
}
sub hablar {
my ($self) = @_;
print "$self->{nombre} hace un sonido\n";
}
1;
```
```perl
package Perro;
use strict;
use warnings;
use parent 'Animal';
sub hablar {
my ($self) = @_;
print "$self->{nombre} dice Guau!\n";
}
1;
```
```perl
use strict;
use warnings;
use Animal;
use Perro;
my $animal = Animal->new(nombre => "Generico");
my $perro = Perro->new(nombre => "Buddy");
$animal->hablar(); # Generico hace un sonido
$perro->hablar(); # Buddy dice Guau!
```
### Herencia Multiple
```perl
package MiClase;
use strict;
use warnings;
use parent qw(Parent1 Parent2);
```
### SUPER
```perl
package Perro;
use strict;
use warnings;
use parent 'Animal';
sub hablar {
my ($self) = @_;
$self->SUPER::hablar(); # Llamar el hablar del padre
print "$self->{nombre} dice Guau!\n";
}
1;
```
## Funcion ref
### Verificando Referencias
```perl
use strict;
use warnings;
my $ref = \$scalar;
my $arr_ref = \@array;
my $hash_ref = \%hash;
my $obj = MiClase->new();
print ref($ref); # SCALAR
print ref($arr_ref); # ARRAY
print ref($hash_ref); # HASH
print ref($obj); # MiClase (blessed) o ""
# Verificar si es objeto
if (blessed($obj)) { # Scalar::Util
print "Objeto de clase ", ref($obj), "\n";
}
```
## Wantarray en Metodos
### Metodos Conscientes del Contexto
```perl
package Pila;
use strict;
use warnings;
sub new {
my ($class) = @_;
return bless [], $class;
}
sub push {
my ($self, @items) = @_;
push @$self, @items;
}
sub pop {
my ($self) = @_;
return pop @$self;
}
sub todos {
my ($self) = @_;
if (wantarray) {
return @$self;
}
return scalar @$self;
}
1;
```
```perl
use strict;
use warnings;
use Pila;
my $pila = Pila->new();
$pila->push(1, 2, 3);
my @items = $pila->todos(); # Contexto de lista
my $count = $pila->todos(); # Contexto escalar (3)
```
## Destructores
### Metodo DESTROY
```perl
package Archivo;
use strict;
use warnings;
sub new {
my ($class, $nombrearchivo) = @_;
open my $fh, "<", $nombrearchivo or die "No se puede abrir: $!";
return bless { fh => $fh, nombrearchivo => $nombrearchivo }, $class;
}
sub leer_linea {
my ($self) = @_;
return <$self->{fh}>;
}
sub DEMOLISH {
my ($self) = @_;
close $self->{fh} if $self->{fh};
print "Archivo $self->{nombrearchivo} cerrado\n";
}
1;
```
## Moose (OOP Moderna)
### Introduccion a Moose
```perl
package Persona;
use strict;
use warnings;
use Moose;
has 'nombre' => (
is => 'rw',
isa => 'Str',
required => 1,
);
has 'edad' => (
is => 'rw',
isa => 'Int',
default => 0,
);
sub saludar {
my ($self) = @_;
return "Hola, soy $self->nombre";
}
__PACKAGE__->meta->make_immutable;
1;
```
### Usando Moose
```perl
use strict;
use warnings;
use Persona;
my $persona = Persona->new(nombre => "Alice", edad => 30);
print $persona->saludar();
$persona->edad(31);
print $persona->edad;
```
### Tipos de Moose
```perl
package Punto;
use strict;
use warnings;
use Moose;
use MooseX::Types::Moose qw(Int Num Str);
has 'x' => (
is => 'rw',
isa => 'Int',
);
has 'y' => (
is => 'rw',
isa => 'Int',
);
sub distancia {
my ($self, $otro) = @_;
my $dx = $self->x - $otro->x;
my $dy = $self->y - $otro->y;
return sqrt($dx*$dx + $dy*$dy);
}
__PACKAGE__->meta->make_immutable;
1;
```
## Moo (Moose Liviano)
### Basicos de Moo
```perl
package Persona;
use strict;
use warnings;
use Moo;
has nombre => (
is => 'rw',
required => 1,
);
has edad => (
is => 'rw',
default => 0,
);
sub saludar {
my ($self) = @_;
return "Hola, soy $self->nombre";
}
1;
```
## Roles (Mixins)
### Roles Basicos
```perl
package Imprimible;
use strict;
use warnings;
use Moose::Role;
requires 'como_cadena'; # La clase consumidora debe implementar
sub imprimir {
my ($self) = @_;
print $self->como_cadena, "\n";
}
1;
```
### Aplicando Roles
```perl
package Documento;
use strict;
use warnings;
use Moose;
with 'Imprimible';
has 'contenido' => (is => 'rw');
sub como_cadena {
my ($self) = @_;
return $self->contenido;
}
__PACKAGE__->meta->make_immutable;
1;
```
## blessed y Scalar::Util
### Verificando Objetos
```perl
use strict;
use warnings;
use Scalar::Util qw(blessed reftype);
my $obj = AlgunaClase->new();
print blessed($obj); # "AlgunaClase" o undef
print reftype($obj); # "HASH", "ARRAY", etc.
if (blessed($obj) && $obj->isa('AlgunaClase')) {
print "Es un objeto de AlgunaClase\n";
}
```
## Resumen
- Las clases se crean con `bless` y package
- El operador `->` llama metodos sobre objetos
- Arreglo `@ISA` para herencia
- `SUPER::metodo` llama implementacion del padre
- `ref` retorna nombre de paquete para refs blessed
- `DESTROY` para limpieza cuando se destruyen objetos
- Moose/Moo proporcionan caracteristicas OOP modernas
- Los roles proporcionan composicion sin herencia
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →