Modulos
## Objetivos de Aprendizaje
- Comprender paquetes y modulos
- Usar @INC y carga de modulos
- Crear y usar modulos
- Trabajar con CPAN
- Usar Exporter para exportaciones
## Paquetes
### Declaracion de Paquete
```perl
package MiPaquete;
# Variables de paquete
our $VERSION = "1.0";
sub hola {
print "Hola desde MiPaquete!\n";
}
1; # Debe retornar verdadero
```
### Alcance de Paquete
```perl
package MiPaquete;
my $privado = "no visible";
our $publico = "visible";
sub test {
print "$publico\n"; # OK
print "$privado\n"; # OK dentro del mismo archivo
}
package main;
print "$MiPaquete::publico\n"; # Acceder con paquete::
# print "$MiPaquete::privado\n"; # Error - no visible
```
## Modulos vs Paquetes
### Archivos de Modulo
```perl
# MiModulo.pm
package MiModulo;
use strict;
use warnings;
sub saludar {
return "Hola!";
}
1; # Terminar con valor verdadero
```
### Usando Modulos
```perl
use strict;
use warnings;
# Referencia directa de paquete
use MiModulo;
print MiModulo::saludar(), "\n";
# O cargar en tiempo de ejecucion
require MiModulo;
```
## use vs require
### use
```perl
use strict; # Carga en tiempo de compilacion
use warnings;
use Mi::Modulo; # Archivo .pm encontrado automaticamente
# Con importacion
use List::Util qw(sum max);
print sum(1, 2, 3); # 6
```
### require
```perl
require Some::Module; # Carga en tiempo de ejecucion
# O requerir un archivo especifico
require "/ruta/a/MiModulo.pm";
```
## @INC
### Entendiendo @INC
```perl
use strict;
use warnings;
# @INC contiene directorios para buscar modulos
print join "\n", @INC;
# Agregar directorio a @INC
use lib "/mi/ruta/personalizada";
BEGIN {
unshift @INC, "/mi/ruta";
}
```
### Encontrando Rutas de Modulos
```perl
use strict;
use warnings;
# En tiempo de ejecucion
perl -e 'print join "\n", @INC'
# En codigo
foreach my $ruta (@INC) {
print "$ruta\n";
}
```
### PERL5LIB
```bash
export PERL5LIB=/mi/lib/personalizada:$PERL5LIB
perl script.pl
```
## Creando Modulos
### Plantilla Basica de Modulo
```perl
package Mi::Modulo;
use strict;
use warnings;
our $VERSION = "1.00";
sub new {
my ($class, %args) = @_;
my $self = bless \%args, $class;
return $self;
}
sub saludar {
my ($self) = @_;
return "Hola, $self->{nombre}!";
}
1;
```
### Estructura de Archivo de Modulo
```perl
# lib/Mi/Modulo.pm
package Mi::Modulo;
use strict;
use warnings;
our $VERSION = '1.00';
sub new {
my ($class, %args) = @_;
return bless \%args, $class;
}
1;
```
## Exporter
### Exporter Basico
```perl
package Mi::Utils;
use strict;
use warnings;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(celsius_a_fahrenheit sumar_numeros);
our @EXPORT_OK = qw(multiplicar_numeros);
sub celsius_a_fahrenheit {
my ($c) = @_;
return $c * 9/5 + 32;
}
sub sumar_numeros {
my ($a, $b) = @_;
return $a + $b;
}
sub multiplicar_numeros {
my ($a, $b) = @_;
return $a * $b;
}
1;
```
### Usando Exporter
```perl
use strict;
use warnings;
# Obtiene @EXPORT por defecto
use Mi::Utils;
print celsius_a_fahrenheit(100); # 212
# O importar funciones especificas
use Mi::Utils qw(multiplicar_numeros);
print multiplicar_numeros(3, 4); # 12
# No importar nada
use Mi::Utils qw();
```
### Etiquetas de Exportacion
```perl
package Mi::Math;
use strict;
use warnings;
use Exporter;
our @ISA = qw(Exporter);
our %EXPORT_TAGS = (
basico => [qw(sumar restar)],
avanzado => [qw(multiplicar dividir)],
);
our @EXPORT_OK = ( @{ $EXPORT_TAGS{basico} }, @{ $EXPORT_TAGS{avanzado} } );
sub sumar { $_[0] + $_[1] }
sub restar { $_[0] - $_[1] }
sub multiplicar { $_[0] * $_[1] }
sub dividir { $_[0] / $_[1] }
1;
```
```perl
use Mi::Math qw(:basico);
print sumar(5, 3);
```
## CPAN
### Usando CPAN
```bash
cpan Module::Name
cpanm Module::Name # Usando cpanminus
```
### Instalando Modulos
```bash
# Usando cpan
cpan install JSON
# Usando cpanminus (recomendado)
cpanm JSON
# Version especifica
cpanm JSON@2.90
```
### Modulos Populares
| Modulo | Proposito |
|--------|---------|
| JSON | Codificacion/decodificacion JSON |
| LWP::UserAgent | Cliente HTTP |
| DBI | Interfaz de base de datos |
| Mojo::DOM | Analisis HTML |
| DateTime | Manejo de fecha/hora |
| Catalyst | Framework web |
| Dancer2 | Framework web ligero |
| Test::More | Pruebas |
| Moose | Framework OOP |
| Moo | OOP ligero |
### cpanfile
```perl
# cpanfile
requires 'JSON', '2.00';
requires 'List::Util', '1.45';
requires 'Path::Tiny';
on 'test' => sub {
requires 'Test::More', '0.98';
requires 'Test::Fatal', '0.013';
};
```
## Pragmas
### use strict
```perl
use strict;
# Requiere:
# - Declaracion de variable (my/our)
# - Calificacion de paquete para globales
# - Proteccion de palabras desnudas
my $var = "test";
# $nodeclarada = "error"; # Daria error
```
### use warnings
```perl
use warnings;
# Advierte sobre:
# - Usar valores undef
# - Filehandles de palabras desnudas
# - Sombreado de palabras clave
# - etc.
```
### Otros Pragmas
```perl
use integer; # Aritmetica de enteros
use bytes; # Semantica de bytes
use utf8; # UTF-8 en fuente
use encoding 'utf8'; # UTF-8 en E/S
use autodie; # Manejo automatico de errores
use feature 'say'; # Caracteristicas modernas
use 5.010; # Version minima de Perl
```
## Modulos Orientados a Objetos
### Clase Basica
```perl
package Punto;
use strict;
use warnings;
sub new {
my ($class, %args) = @_;
my $self = bless {
x => $args{x} // 0,
y => $args{y} // 0,
}, $class;
return $self;
}
sub x { my $s = shift; $s->{x} = shift if @_; $s->{x} }
sub y { my $s = shift; $s->{y} = shift if @_; $s->{y} }
sub distancia {
my ($s, $otro) = @_;
my $dx = $s->x - $otro->x;
my $dy = $s->y - $otro->y;
return sqrt($dx*$dx + $dy*$dy);
}
1;
```
### Usando la Clase
```perl
use strict;
use warnings;
use Punto;
my $p1 = Punto->new(x => 0, y => 0);
my $p2 = Punto->new(x => 3, y => 4);
print $p1->distancia($p2); # 5
```
## Estructura de Directorio de Modulos
### Diseno Estandar
```text
lib/
Mi/
Modulo.pm
t/
test.t
Makefile.PL # o Build.PL
MANIFEST
README
```
### Makefile.PL
```perl
use ExtUtils::MakeMaker;
WriteMakefile(
NAME => 'Mi::Modulo',
VERSION_FROM => 'lib/Mi/Modulo.pm',
PREREQ_PM => {
'strict' => 0,
'warnings' => 0,
},
INSTALLDIRS => 'site',
);
```
## Resumen
- Los paquetes agrupan codigo y proporcionan espacios de nombres
- Los modulos son archivos .pm que contienen paquetes
- `use` carga en tiempo de compilacion, `require` en tiempo de ejecucion
- `@INC` contiene rutas de busqueda para modulos
- `Exporter` maneja exportaciones de funciones
- CPAN proporciona miles de modulos reutilizables
- Siempre usar `strict` y `warnings`
- El modulo debe retornar verdadero al final
- Usar `our` para variables con alcance de paquete
Comments
Comments powered by Giscus
To enable comments, add your Giscus embed code here.
Learn more about Giscus →