el evangelio de
Perl
segun carlos jaramillo
tabla de contenido
lo basico...
que es perl
sobre este documento
variables
valores
mas sobre arreglos
mas sobre hashes
verdadero y falso
operadores
funciones
bloques
mas funciones integradas
enunciados
referencias
archivos
regex
mas sobre regex
variables especiales
lo bueno... aqui se le saca la utilidad...
paquetes
objetos
2 clases de metodos
el modulo CGI
el modulo DBI
algo mas... siempre es bueno saber mas...
mas sobre archivos
como procesa perl un programa
la linea de comando de perl
mas sobre contexto
herencia de objetos
lo basico...
que es perl
perl es un lenguaje de computador interpretado muy original...
tiene cosas de C, de los shell de unix, de awk, de sed...
y de los lenguajes humanos...
creo que un programador de perl remplaza varios de c
sobre todo porque el programador gana mucho tiempo... no tiene que
pensar si la variable es numerica o caracter... no tiene que
pensar si el valor cabe en la variable...
y por supuesto no hay que compilar... lo que no quiere decir que
perl sea lento...
tampoco hay duda de que perl se aprende rapido... al menos lo basico...
es muy facil hacer pequeños programas para aclarar rapidamente las dudas...
esta tambien la ventaja de su portabilidad... yo tengo perl en todas las
maquinas que uso: unix svr4, linux, W95... es como volver a la epoca en que
todos los computadores tenian basic... solo que perl es superior a cualquier
lenguaje que yo haya visto...
sobre este documento
este documento pretende ayudar a utilizar y a popularizar perl...
aunque el perl corre en W95/NT mi interes principal es unix...
y por supuesto linux...
me gustaria que el documento fuera util a gente que trabaja con CGIs...
osea las paginas dinamicas de internet/intranet... y a la gente que trabaja con
Oracle... creo que la combinacion de perl CGI y Oracle es insuperable...
estoy ensayando un estilo de escritura conversacional... frases cortas...
la idea es que las frases se entiendan rapidamente...
que el documento sea corto...
ahora si vamos al grano...
variables
para empezar no es necesario predefinir la variables...
se pueden empezar a usar variable directamente en las expresiones
existen 3 tipos basicos de variables
1. escalares - las variables escalares empiezan por $
$a = 5;
$b ="xxx";
$c = $a++; # $a++ es como en c osea $a + 1
note esto sobre las instrucciones:
las instrucciones terminan en punto y coma...
perl se confunde muy facil si se olvida el punto y coma
note esto sobre comentarios
todo lo que este despues de # en la misma linea
es un comentario
note esto sobre escalares:
escalar puede tener numeros, strings y otras cosas
mas complicadas como referencias y descriptores
2. arreglos - variables arreglos empiezan por @
@a = (95, 7, 'fff' );
print $a[2];
# el tercer elemento osea imprime: fff
print @a
# imprime: 957fff ...todo pegado
note esto sobre arreglos:
los elementos de un arreglo son escalares que empiezan por $
los subindices empiezan por 0 como en c
el escalar $a no tiene que ver nada con $a[ ]
nota sobre print
print es una de las muchas funciones de perl
en perl hay mucha flexibilidad para escribir los argumentos
print ( $a, $b ); # con parentesis
print $a, $b; # sin parentesis
3. hashes - arreglos asociativos - variables empiezan por %
para crear un elemento de un hash se requiere una lista de 2 valores
el primer elemento es la clave y el segundo es el valor
%a = ( 'x', 5, 'y', 3);
# llena 2 elementos del hash
print $a{'x'};
# imprime: 5
print $a{'y'};
# imprime: 3
si la clave es un string sencillo se puede omitir las comillas
$a{x} es lo mismo que $a{'x'}
si se reasigna un elemento se pierde el valor viejo
%a = ('x', 5, 'y', 3 );
$a{x}=7;
print $a{x};
# imprime: 7
note esto sobre los hashes
los elementos se accesan por claves
no hay claves duplicadas
valores
los valores son las cosas que uno mete a las variables...
en perl los valores se guardan aparte de las variables e incluso
cada valor tiene un contador que indica cuantas variables lo estan
usando... cuando el contador es cero el valor desaparece
valores interesantes:
1. los strings
los strings pueden escribirse con comillas dobles o simples
$a = "abcd";
$a = 'abcd';
cuando se usa doble comilla se pueden interpolar variables escalares y arreglos
...interpolar significa intercalar... en el resultado final la variable se
sustituye por su valor...
$a = 'pueblo'
print "hola $a";
# imprime: hola pueblo
print 'hola $a';
# no hay interpolacion en comillas simples...
# imprime: hola $a
como se interpola una variable entre letras sin que se altere el nombre
de la variable...p.e. como se coloca $a antes de una letra como "s"
"abc$as";
# no sirve... trata de interpolar la variable $as
"abc${a}s"
# interpola corectamente $a
entre las comillas dobles se pueden tambien poner caracteres especiales como
salto de line \n, tabulador \t, backspace \b,...
print "aaa \n";
# salta linea
print 'aaa \n';
# no salta... imprime: aaa \n
entre las comillas doble. se tiene que escapar los caracteres que tienen
significado especial en perl... como $, ", \ ...
$a = 1234;
print "valor=$a\$";
# imprime: valor=1234$
"escapar" significa ponerle un backslash antes
entre las comillas simples solo se tiene que "escapar" ' y \
print 'abc\'s';
# imprime: abc's
cuando se interpola un arreglo perl regala un separador que es un blanco
@a = (95, 7, "fff" );
print "val=@a" ;
# imprime: val=95 7 fff
el separador es realmente el valor de la variable escalar $"
$" puede ser reasignada
$" = ',';
print "val=@a";
# imprime: val=95,7,fff
2. las listas
p.e (2, 7, 'sss' )
$a = (2, 7, 'sss');
# $a queda con el ultimo valor osea 'sss'
@a = (2, 7, 'sss');
$a = @a;
# $a queda con el numero de elementos de @a osea 3
note que (2, 7, 'sss') es un valor
mientras que @a es un arreglo - recuerde que las variables y los
valores son 2 cosas distintas
existen unas abreviaturas para algunas listas
$a = (2..7);
# $a queda con (2,3,4,5,6,7);
$a = ('a'..'e');
# $a queda con ('a','b','c','d','e')
3. strings con comillas invertidas
las comillas invertidas se comportan como en los shelles de unix
$a = `ls -l`; # $a queda con la salida del comando "ls -l"
en comillas invertidas se puede usar interpolacion de variables
en comillas dobles se puede usar interpolar comillas invertidas
asociar un valor con una variable se llama bind...
$a = 5;
# aqui 5 es el valor de $a
$b = $a;
# aqui el valor 5 de $b es otro valor
# para que se utilice un solo valor para 2 variables se necesita
# utilizar referencias... referencias se ven mas adelante...
mas sobre arreglos
los subindices positivos recorren los elementos al derecho
@a = ('a'..'e');
$a[0] es 'a' $a[4] es 'e'
los subindices negativos recorren los elementos al revez
@a = ('a'..'e');
$a[-1] es 'e' $a[-5] es 'a'
un arreglo en contexto escalar retorna el numero de elementos
@a = ('a'..'e');
$n = @a;
# aqui $n es 5
lo del contexto es una caracteristica de perl...
perl evalua una expresion segun el uso que se piensa
dar a la expresion... contexto escalar o contexto de lista
subarreglos:
@a = ('a'..'e');
@b = @a[3, 0];
# @b = ('d', 'a');
@c = @a[2-5];
# @a[2,3,4,5] o @a[2..5]
es posible colocar una lista de variables escalares a la izquierda del igual
($a, $b ) = @x
# $a queda con el valor de $x[0]
# $b queda con el valor de $x[1]
es posible colocar un subarreglo a la izquierda del igual
@a[3, 0] = @a[0, 3];
# intercambia los elementos 0 y 3
la funcion join convierte un arreglo en un escalar
@a = ('a'..'e');
$a = join ":", @a
# $a queda con "a:b:c:d:e";
la funcion split convierte un escalar en un arreglo... muy util para
separar los campos en un registro de un archivo texto
$a = 'a:b:c:d:e';
# no se le parece esto al /etc/passwd?
@a = split /:/, $a
# @a queda con ('a', 'b', 'c', 'd', 'e')
aqui el segundo parametro es mas que un string...
es una regex que es un cuento largo que se ve mas adelante
la funcion shift entrega el 1er elemento del arreglo y ademas le quita ese
elemento al arreglo
@a = ('a'..'e');
$b = shift @a;
# $b queda con 'a'
# @a queda con ('b'..'e');
la funcion pop entrega el ultimo y bota el ultimo del arreglo
@a = ('a'..'e');
$b = pop @a;
# $b queda con 'e'
# @a queda con ('a'..'d');
se puede intuir que hacen las funciones unshift y push...
unshift @a, 'a';
# agrega 'a' al principio del arreglo
push @a, 'e';
# agrega 'e' al final del arreglo
unshift y push pueden tambien agregar una lista de elementos
en lugar se un solo elemento
la funcion splice permite extraer un subarreglo
y modificar a la vez el arreglo original...
@a = ( 'a'..'e');
@b = splice ( @a, 1, 2);
# @b queda con 2 elementos de @a: $a[1] y $a[2];
# osea ( 'b', 'c')
# @a queda sin esos 2 elementos
# osea ( 'a', 'd', 'e' );
splice con un argumento mas sirve para parchar el arreglo original
@a = ( 'a'..'e');
@b = ( 1..3);
splice ( @a, 2, 1, @b);
# @a queda con ('a', 'b', 1, 2, 3, 'd', 'e');
# se cambio 'c' por (1, 2, 3)
tambien se puede parchar sin botar nada...
@a = ( 'a'..'e');
@b = ( 1..3);
splice ( @a, 2, 0, @b);
# @a queda con ('a', 'b', 1,2,3, c', 'd', 'e');
mas sobre hashes
para que sea mas claro la asignacion a un hash se pueden remplazar
algunas comas por "=>"...
%x = ( 'ope' => 'ver', 'nit' => 890900285 );
asi se ven mejor las parejas clave-valor
en cualquier momento se puede agregar un elemento a un hash
$a{fac}=3456;
para borrar un elemento
delete $a{ope};
la funcion keys crea un arreglo con las claves de un hash
%a = ( x => 5, y => 3, z => 'abc' );
@b = keys %a
# @b queda con ( 'x', 'y', 'z');
la funcion values devuelve un arreglo con los valores del hash
%a = ( x => 5, y => 3, z => 'abc' );
@v = values %a
# @v queda con ( 5, 3, 'abc' );
la funcion exists devuelve 0 si no no existe la key en el hash
%a = ( x => 5, y => 3, z => 'abc' );
$x = exists $a{w};
# $x queda con 0
verdadero y falso
ademas de las expresiones logicas... cualquier expresion tiene un
significado booleano...
p.e. las asignaciones tienen el valor de lo asignado...
cuales valores son falsos...
1. los strings "" and "0"
2. el numero 0.
3. el valor "no definido" de una variable
osea cuando existe la variable pero no tiene valor
obviamente todo lo demas valores son verdaderos
la funciones defined se usa para averiguar si una variable esta definida
$a = 5;
print "a definida" if ( defined $a ) ;
print "b no definida" if ( ! defined $b ) ;
nota sobre los if
el if escrito al revez es muy comodo porque uno se
ahorra las llaves
en el if normal nunca se pueden omitir las llaves
if ( defined $a )
{
print "a definido";
}
ojo que la funcion undef no es lo contrario de defined... lo que hace
realmente es volver el argumento "no definido"... elimina el bind entre la
variable y el valor... el valor desaparece si su contador de referencias
queda en cero
operadores
operadores logicos
operadores para comparar numeros... como en c
print "a igual a b" if ($a == $b);
print "a distinto de b" if ($a != $b);
print "a >= b" if ($a >= $b);
para comparar strings se usan otros operadores
print "a igual a b" if ($a eq $b);
print "a distinto ab" if ($a ne $b);
print "a >= b" if ($a ge $b);
el siguiente ejemplo muestra porque se necesita distinguir
una comparacion numerica de una comparacion de strings
$a=5; $b=49;
$x = ($a gt $b)
# $x queda 1 ( verdadero)
$x = ($a > $b)
# $x queda "" ( falso)
comparacion de numeros ( starship operator )
$x = $a <=> $b
# $x queda con -1 si $a < $b
# $x queda con 0 si $a == $b
# $x queda con 1 si $a > $b
comparacion de strings
$x = $a cmp $b
# $x queda con -1 si $a lt $b
# $x queda con 0 si $a eq $b
# $x queda con 1 si $a gt $b
operador ternario
una abreviatura de las 3 partes de algunos if...
la condicion , la accion para verdadero y la accion
para falso... separdos por ? y :
@a > 5 ? print "a > 5": print "a no es > 5";
operadores de strings
repetir strings con operador "x"
$a = "y";
$b = $a x 5
# $b queda con "yyyyy";
concatenar strings con operador "."
$a = "abc"
$b = $a . "def" ;
# $b queda con "abcdef"
operador de rango ".." para hacer listas
@a = "ay" .. "bb";
# @a queda con ("ay", "az", "ba", "bb")
@a = 1..5;
# @a queda con (1, 2, 3, 4, 5)
ojo no mezcle letras y numeros
ojo no mezcle mayusculas y minusculas
funciones
en perl se puede definir una funcion es cualquier parte...
la funcion solo se ejecuta cuando se llama expresamente
la funcion se define con sub
sub fun1
{
$a = shift;
# shift asume el arreglo @_
# @_ es el arreglo que tiene los argumentos
# que se dan al llamar la funcion
$y = 2 * $a;
return ( $y );
# devuelve ese valor al que llamo la funcion
}
la funcion se llama con &
$z = &fun1( $x );
# pasa $x como unico elemento de @_
# osea $_[0]
una funcion que no tiene "return" de todas maneras retorna algo...
retorna el valor de la ultima expresion...
esto quiere decir que la funcion fun1 arriba no necesita el "return"
no es obligacion que el llamador utilice el valor del return... como en c...
los parametros de una funcion se pasan por referencia...
osea que si se modifica $_[1] se alteraria el 2do parametro usado
en la expresion llamadora... algo peligroso
sub fun1
{
$_[0]=7; # altera el 1er parametro en el llamador
}
$a = 5;
&fun1($a);
print $a; # imprime: 7
bloques
un bloque son expresiones dentro de llaves
las funciones que vimos son bloques pero tambien puede haber bloques
sin la palabra sub...
una de las razones para tener bloques es tener variables locales
que desaparecen cuando el bloque termina...
$a = 5;
# variable global que nunca muere
{
$b = 7;
# variable global que nunca muere
my ( $c ) = 3;
# "my" crea una variable local
# solo existe en este bloque
&fun1 ()
# dentro de fun1 $c no es visible
}
print $a; # imprime: 5
print $b; # imprime: 7
print $c; # error... variable no existe
sub fun1
{
print $a; # imprime: 5
print $b; # imprime: 7
print $c; # error... variable no existe
}
la funcion my es la mas utilizada para definir variables locales...
las variables locales "my" o lexicas son visibles solo dentro del bloque...
no son visibles fuera del bloque... tampoco son visibles a las funciones que
se llaman desde el bloque...
la otra funcion local que se usa para definir variables locales es bastante
curiosa... para empezar no es realmente local sino global... solo que
el valor global se altera provisionalmente...
$a = 5; # variable global que nunca muere
{
local ( $a ) = 3;
# el viejo valor 5 se guarda provisionalmente
# para reponerlo cuando este bloque termine
local ( $b ) = 7;
# como $b no existia entonces
# se guarda "no definido" provisionalmente
# para recordarlo cuando este bloque termine
&fun1 ();
# en fun1 se puede usar $a y $b
}
print $a; # imprime: 5
print $b; # error... variable "no definida"
sub fun1
{
print $a; # imprime: 3
print $b; # imprime: 7
}
mas funciones integradas
funciones de strings
chop ($a);
bota el ultimo caracter del valor de $a
$a = "abcdef";
chop ( $a ) ; # $a queda con "abcde";
muy usado para quitar el caracter "\n"
al final de una linea de un archivo texto
length ( $a)
devuelve la longitud del valor de $a
$a = "abcdf";
print length ( $a ); # imprime: 5
index ( $a , $x );
devuelve la posicion de $x en $a
$a = "abcdef";
$b = index ( $a, "cd" );
print $b; # imprime: 2
uc ( $a );
devuelve los caracteres de $a en mayusculas
lc ( $a );
devuelve los caracteres de $a en minusculas
substr ( $a, $pos, $len );
extrae un string de otro
el 2do parametro es la posicion para empezar
el 3er parametro es la longitud
$a = "abcdef";
print substr ($a, 2, 3);
# imprime: cde
interesante uso de substr al lado izquierdo de una asignacion
$a = "abcdef";
substr ( $a, 2, 3 ) = "xy";
# cambia "cde" por "xy"
print $a
# imprime: abxyf
funciones de arreglos
@b = map ( uc($_), @a )
devuelve un arreglo despues de applicar una funcion a cada uno;
@a = ('ax'..'bc' );
@b = map ( uc($_) ), @a;
print "@b"; # imprime: AX AY AZ BA BB BC
@b = grep /^b/ , @a;
devuelve un subarreglo de @a... que contiene los elementos
donde la expresion es verdadera... en este caso los que empiecen por "b"
@a = ("a1", "a2", "b1", "b2", "c1", "c2");
@b = grep /^b/, @a;
print "@b"; # imprime: b1 b2
el arreglo que devuelve grep se usa tambien como un valor
booleano... falso si ningun elemento del arreglo cumple la condicion...
@b = sort ( @a )
devuelve un arreglo ordenado
ojo que el ordenado es @b... @a sigue desordenado...
claro que se puede hacer @a = sort @a inpunemente...
funciones de hash
@b = each ( %a );
@b es una lista de 2 elemtos ($key, $value)... correspondiente
a un elemto del hash %a... cuando se llama varias veces con el mismo
hash itera sobre todos los elementos del hash...
while ( ($k, $v ) = each ( %a ) )
{
print ( "key=$k val=$v \n");
}
... aunque yo prefiero hacer lo anterior asi:
foreach ( keys %a )
{
print ( "key=$_ val=$a{$_} \n");
}
foreach trabaja sobre un arreglo... recorre el bloque por cada elemto
del arreglo... $_ es cada elemento del arreglo...
tambien es posible usar foreach con otra variable distinta de $_
foreach $k ( keys %a )
{
print ( "key=$k val=$a{$k} \n");
}
enunciados
un "if" mas completo... observe el "elsif "
if ( /^[1..3]/ ) # expresion regular que se explica mas adelante
{
print "$_ es cta de balance\n";
}
} elsif ( /^[4..7]/ )
{
print "$_ es cta de resultado\n";
} else
{
print "$_ es cta de orden\n";
}
# el elsif ahorra parentesis y ahorra indentaciones
nuevamente el foreach...
@a = (1..5);
foreach ( @a )
{
$_ = "x" if ($_ == 3);
}
print "@a"; # imprime: 1 2 x 4 5
ojo que $_ es un alias temporal de cada elemento del arreglo
... osea que si se modifica $_ se altera el arreglo...
...pero tambien $_ es variable local tipo "my" que no afecta
ningun $_ global... ni es visible en subrutinas que se llamen desde
dentro del foreach...
palabras de salto
last; salta fuera del bloque actual
next; omite los enunciados que faltan
y comienza una nueva iteracion
redo; reinicia bloque de enunciados
un while mas complicado...observe el bloque "continue"
while ( /^\d/ )
{
next if ( /^47/ );
print "empieza por digito\n";
} continue
{
# esto se hace antes de repetir la condicion del while
# y aunque se use next dentro del while
<f1>; # lea un registro de un archivo
}
referencias
las referencias son escalares que apuntan al valor de otra variable...
"apuntan a" significa "tiene la direccion de"...
$ra = \$a; # referencia a escalar
$rb = \@b; # referencia a arreglo
$rc = \%c; # referencia a hash
$rx = \$rb; # referencia a referencia
tambien hay referencias a funcion y referencias a objetos...
las referencias interesantes son a arreglos y a hashes...
veamos otra forma de crear una referencias a arreglo...
observe el parentesis cuadrado
$rb = [ 'e1', 'e2', 'e3'];
aqui el arrray no tiene nombre...
$rb es una referencia a un arreglo anonimo...
otra forma de crear una referencia a hash... observe las llaves
$rc = { k1 => 'v1', k2 => 'v2' };
aqui el hash no tiene nombre...
$rc es una referencia a un hash anonimo...
cuando una referencia es dereferenciada se obtiene el dato real
$ra = \$a; # referencia a escalar
$rb = \@b; # referencia a arreglo
$rc = \%c; # referencia a hash
$rx = \$rb; # referencia a referencia
${$ra) es la desreferencia de $ra... el valor de $a
@{$rb) es la desreferencia de $rb... el valor de @a
@{$ra) es un error porque $ra apunta a un escalar
%{$rc} es la desreferencia de $rc... el valor de %c
veamos una manera de accesar los elementos de un hash usando una referencia...
muy util si el hash es anonimo...
$rc = { a => 1, b => 2 };
# $rc es una referencias a un hash anonimo
print $rc->{a};
# imprime: 1
la funcion ref
devuelve un string que indica el tipo del referenciado
$ra = \$a; # referencia a escalar
$rb = \@b; # referencia a arreglo
$rc = \%c; # referencia a hash
$rx = \$rb; # referencia a referencia
$rf = \&f; # referencia a funcion
ref ( $ra ); # devuelve "SCALAR"
ref ( $rb ); # devuelve "ARRAY"
ref ( $rc ); # devuelve "HASH"
ref ( $rx ); # devuelve "REF"
ref ( $rf ); # devuelve "CODE"
si el operando de ref no es una referencia, ref devuelve falso "no definido"
la funcion bless
cambia el tipo de una referencia a otro tipo...
muy utilizado para crear clases
$rc = { ano => 1995, marca => 'renault', puertas => 4 };
ref ( $rc );
# devuelve "HASH"
bless $rc "CARRO";
ref ( $rc );
# devuelve "CARRO"
# esto tiene mas sentido cuando se hable de objetos y paquetes...
diferencia entre trabajar con variables y trabajar con referencias...
$a = 5;
$b = $a;
# $b recibe una copia del valor de $a
$a = 7;
print "$a $b\n";
# imprime: 7 5
# un cambio en $a no afecta a $b
$a = 5;
$ra = \$a;
$rb = $ra;
$a = 7;
print "$a $$ra $$rb \n" ;
# imprime 7 7 7
# las referencias si comparten en mismo valor...
# el valor 7 aqui tiene 3 usuarios...
archivos
abrir archivos...
open f1, "auxytd.98.3";
abre un archivo de lectura... el archivo se maneja con el descriptor f1 ...
f1 es como el descriptor de c...
otras formas de open...
open f1, "< auxytd.98.3";
# abrir para leer...
# el < se puede omitir...
open f1, "> auxytd.98.3";
# abrir para escribir
open f1, ">> auxytd.98.3";
# abrir para agregar
leer un archivo texto... osea cuando cada linea termina en "\n"
el operador diamante "<>" lee una linea del archivo
open f1, "auxytd.98.3";
while ( <f1> )
{
print;
}
aqui <f1> llena $_ con una linea del archivo... que posteriormente
se imprime con print... en perl casi todo el mundo asume $_ ...
en realidad <f1> en contexto escalar leen una linea... y en
contexto lista lee todo el archivo...
open f1, "auxytd.98.3";
@a = <f1>;
# @a tiene todo el archivo
# cada elemento de @a es una linea del archivo
escribir en un archivo con print
print descriptor @lista
ojo que no hay coma entre descriptor y @lista
si no hay descriptor se asume STDOUT
si no hay @lista se asume $_
regex
regex es una abreviatura de expresion regular
una expresion regular es una forma general de indicar un patron de caracteres
que queremos buscar en un string... usualmente el patron se escribe entre slashes
las regex se utilizan en 3 clases de expresiones
1. match del patron en un string...
aqui la regex es una expresion booleana...
devuelve verdad si el string contiene un patron
$a = "abcdef";
$a =~ /bc/; # es verdadero
$a =~ /ba/; # es falso
"=~" se llama el operador de bind...
"!~" es la negacion de la expresion
$a = "abcdef";
$a !~ /bc/; # es falso
$a !~ /ba/; # es verdadero
2. sustitucion... s///
muy util para remendar strings...
$a = "<option>mod";
$a =~ s/>/ selected>/
print $a;
# imprime: <option selected>mod
3. traduccion... tr/ / /
$a = "f1=abc test=on";
tr/=/ / ;
# $a queda "f1 abc test on"
%x = split / /, $a;
$x{f1} queda "abc"
$x{test} queda "on";
cuando el escalar es $_ se omite $_ y =~...
$_ = "abcdef";
/bc/; # es verdadero
s/cd//;
print; # imprime: abef
cuantificadores
se usan para indicar que algunas letras se repiten
* : cero o mas del anterior caracter
+ : uno o mas del anterior caracter
? : cero o un del anterior caracter
{3,5} : minimo 3 y maximo 5 del caracter anterior
{3,} : minimo 3 del caracter anterior
{,5} : maximo 5 del caracter anterior
$_ = "abcccd";
/c+d/ ; # es verdadero
puntos de referencia
^ : es el comienzo del string
$ : es el final del string
\b : es un borde de una palabra [palabras son letras numeros y _ ]
$_ = "abcdef";
/^abc/; # es verdadero
clases de caracteres comunes
. : un caracter cualquiera
\s : un epacio en blanco , tabulador o salto de linea
\S : un caracter no blanco, no tabulador y no salto de linea
\d : un digito
\D : un no digito
\w : un caracter de palabra: digito letra o _
\W : un caracter que no es de palabra
$_ = "d15";
/\d+$/ ; # es verdadero
clases de caracteres a la medida
[abcef] : uno de esas 5 letras
[a-f] : lo mismo que el anterior
[0-9] : es lo mismo que \d
[\t \n] : es lo mismo que \s
[a-zA-Z_] : es lo mismo que \w
[^a-zA-Z_]: es lo mismo que \W ... aqui ^ significa negacion
@a = ( 1..10);
foreach ( @a )
{
print "$_:" if ( /^[1-3]/ );
}
# imprime: 1:2:3:10:
caracteres especiales
\. : punto
\\ : backslash
\n : salto de linea
\t : tabulador
\$ : signo pesos
mas sobre regex
memoria de matchs...
los parentesis se usan para almacenar los matchs
en las variables $1, $2, $3, hasta $9...
$_ = "1995 renault azul";
s/^(\w+)\s+(\w+)/$2 $1/;
print $a; # imprime: renault 1995 azul
print $1; # imprime: 1995
tambien es posible sacar los matchs a un arreglo
$_ = "1995 renault azul";
@a = /^(\w+)\s+(\w+)/;
print "@a"; # imprime: 1995 renault
como si ya no fuera bastante... las regex tienen tambien opciones...
/g : indica que haga varios "match"
$_ = "f1=abc test=on";
s/=/ / ; # f1 queda con "f1 abc test=on"
$_ = "f1=abc test=on";
s/=/ /g ; # f1 queda con "f1 abc test on"
$_ = "1995 renault azul";
@a = /^(\w+)/g; # @a queda con 3 elementos
claro que el split me parece mejor...
@a = split; # la regex default de split es / +/
/i : ignore mayusculas y minusculas
$_ = "Francisco francisco";
s/francisco/pacho/ig; # $_ queda con "pacho pacho"
s///e : ejecuta la segunda expresion y su valor lo utiliza
para remplazar el patron...
$_ = "largo= 15";
s/(\d+)/$1 * 4/e;
print; # imprime: largo= 60
variables especiales
perl tiene toda su maquinaria a la vista...
variables que afectan arreglos
$[ es el suscrito base de los arreglos [default es 0]
$" el separador de elementos cuando se interpola un arreglo en
un string de comilla doble [default es espacio]
variables utilizadas en archivos
$. contiene el ultimo numero de linea leido
$/ terminacion de registro de entrada [ default es '\n' ]
$| si es diferente de cero se vacea el buffer de salida
despues de print o write (default es 0 )
se debe colocar en 1 para hablar con un puerto de tcp/ip...
variables usadas con patrones
$& contiene el ultimo string que hizo match
$+ contiene el string que coincidio con el ultimo
parentesis que hizo match
$1, $2, $3...
memoria de lo matches de los parentesis
variables usadas en impresion
$\ se agrega al final del print ( default nulo )
variables relacionadas con procesos
$0 el nombre del script de perl
$! numero de error o string con el texto del error
%ENV hash que tiene las variables de ambiente del programa
p.e $ENV { QUERY_STRING )
que lo llena el apache antes de llamar un cgi-bin...
tiene lo que va despues de la ? en el URL del Netscape
variables diversas
$_ parametro default de muchas funciones
es como el "que" del español...
@ARGV argumentos de la linea de comando
un split / +/ de la linea de comando
lo bueno...
paquetes
un paquete es un espacio de nombres...
los espacios de nombrs permiten que nosotros utilicemos codigo de otras personas
sin que las variables de nosotros se confundan con las variables de la otra persona
package C110; # estamos en el espacio de nombres C110
$a = 5; # variable del paquete C110
fun1 # funcion del paquete C110
{
print "$a\n";
}
package D110; # ahora estamos en el espacio de nombres D110
# ...salimos del paquete C110
$a = 7; # esta $a es del paquete D110
print $a; # imprime 7
print $C110::a; # imprime 5
# note como podemos accesar el espacio de nombres
# C110... note el $ y los ::
C110::fun1; # llama a fun1 de C110...imprime: 5
fun1 C110; # llama a fun1 de C110...imprime: 5
C110->fun1; # llama a fun1 de C110...imprime: 5
observe las 3 formas de llamar la funcion...
cuando no usamos "package" estamos trabajando en el espacio de nombres "main"...
como un paquete generalmente se hace para ser reutilizado muchas veces... se guarda
en un archivo libreria de extension .pl como p.e cgilib.pl...
y los programas que lo quieren usar lo invocan con requiere
requiere "cgilib.pl";
la funcion "requiere" lee el archivo "cgilib.pl" si este no ha sido leido antes
... el archivo no tiene que tener "package" pero si debe devolver
verdadero... osea que lo mejor es que termine con: return 1;
las librerias ya no se usan tanto... porque llego la moda de los objetos
que en perl se implementan con modulos...
ojo... parametro adcicional que reciben las funciones de un paquete.
package C110;
sub fun2
{
print "fun2 recibio @_\n";
}
package D110;
C110::fun2("xyz");
# llama a fun2...imprime: fun2 recibio xyz
# esta forma no se utiliza usualmente para llamar funciones
# de modulos porque como veremos mas adelante las funciones de modulos
# se escriben para utilizar un parametro adicional...
C110->fun2("xyz");
# llama a fun2...imprime: fun2 recibio C110 xyz
fun2 C110("xyz");
# equivalente al anterior... C110->fun2 ("xyz")
observe que cuando se llama con C110->fun2, fun2 recibe un
parametro adicional...el nombre del paquete... osea "C110"...
mas adelante veremos otra forma mas de llamar fun2...
$r->fun2()... donde $r es una referencia a un objeto C110...
en este caso el parametro adicional que recibe fun2 es la referencia $r...
un modulo es un paquete en un archivo de su mismo nombre y extension .pm...
los nombres de los modulos empiezan por mayuscula...
p.e el modulo CARRO debe estar en el archivo CARRO.pm
para utilizar un modulo en un programa se utiliza use
la funcion "use" es como un "requiere" pero que ademas ejecuta una funcion
del modulo llamada import... que vamos a ignorar por ahora...
en seguida vermos como los modulos se utilizan pra representar objetos...
objetos
una clase es una abstraccion de un objeto... por ejemplo la clase CARRO...
una clase esta compuesta de propiedades y metodos que para nosotros corresponden
muy bien a variables y funciones...
es bueno distinguir la clase CARRO y un objeto de la clase CARRO...
la clase carro podria tener la propiedad velocidad y la funcion acelerar para
aumentar la velocidad... un carro epecifico podria tener velocidad=50 y llamar
la funcion acelerar(7) para que cambie a velocidad=57;
los modulos se utilizan para representar clases porque los paquetes aislan
muy bien las variables y las funciones... tal como se desea con la moda de
los objetos...lo que se llama "encapsulamiento"...
el ejemplo que sigue utiliza 2 archivos
1. archivo CARRO.pm... para representar la clase CARRO
package CARRO;
# la clase CARRO tiene 3 metodos...
# o el modulo CARRO tiene 3 funciones:
# 1. new: crea objetos tipo CARRO
# 2. acelarar : cambia la velocidad de un objeto CARRO
# 3. status : muestra la velocidad de un objeto CARRO
# el modulo CARRO tiene una variable
# 1. vel: la velocidad del carro
sub new
{ # "new" es el nombre preferido para crear instancias de
# una clase... un recuerdo de c++
my ( $rc );
$rc = { vel => 0 };
# un hash es lo mas recomendado para representar un objecto...
# recuerde que las llaves crean una referencia a un hash anonimo
bless $rc , "CARRO"
# recuerde bless de referencias
# $rc ahora es una referencia a un objeto tipo "CARRO" ...
return $rc;
# devuelve una referencia tipo "CARRO"...
# despues de esto $rc muere... pero el hash anonimo no muere
# si el llamador utiliza el valor del return...
# si la funcion new es llamada de nuevo devuelve tambien
# una referencia "CARRO"... pero de otro hash anonimo que esta
# en otra parte de la memoria...
}
sub acelerar
{
my ( $rc ) = shift;
# el 1er shift entrega un parametro adicional que perl
# antepone a @_ ... en este caso la referencia
# con que nosotros llamamos la funcion en el 2do archivo...
$rc->{vel} += shift;
# el 2do shift entrega el parametro
# con que nosotros llamamos la funcion en el 2do archivo
}
sub status
{
my ( $rc ) = shift;
print "velocidad=$rc->{vel}\n";
}
return 1;
# para que no falle el "use"...
2. archivo 0010.pl... que utiliza el modulo CARRO
#!/usr/bin/perl -w
# el -w es un parametro de perl... para que de buenos warnings
use CARRO;
# como no usamos package... estamos en el package "main"
$x = new CARRO;
# lo mismo que CARRO->new();
# $x queda con una referencia a un tipo "CARRO"...
$y = new CARRO;
# $y es otro CARRO distinto
$x->status;
# otra forma de llamar una funcion del paquete "CARRO"...
# ...con una referencia tipo "CARRO"...
# imprime: velocidad=0
$x->acelerar(50);
# el primer parametro que "acelerar" recibe es $x
# el segundo parametro que "acelerar" recibe es 50
$x->status;
# imprime: velocidad=50
$y->status;
# imprime: velocidad=0
en este ejemplo vemos como el modulo CARRO representa la clase CARRO...
y usando new de la clase CARRO creamos 2 objetos tipo CARRO: $x y $y ...
podemos complicar un poco la funcion new de CARRO.pm para que reciba parametros...
pero hay que anotar que perl le pone un parametro adicional... en este caso el string
"CARRO"...que por ahora no lo necesitamos...
sub new
{
my ( $class ) = shift;
# si new se llama como CARRO->new, $class queda con "CARRO"
# aparentemente esto no es ninguna informacion... pero se vuelve
# muy util cuando se trabaja con objetos "heredados" de CARRO...
# herencia es otro los conceptos modernos de objetos...
my ( $vel, $marca ) = @_;
my $rc = { vel => $vel, marca => $marca };
bless $rc, $class;
}
y el archivo 0010.pl seria...
#!/usr/bin/perl -w
use CARRO;
#x = CARRO->new (50, "renault");
$y = CARRO->new (70, "mazda");
$x->status; # imprime: velocidad=50
$y->status; # imprime: velocidad=70
2 clases de metodos
observe bien las 2 formas de llamar metodos de una clase...
1. CARRO->new(50, "renault") o new CARRO (50, "renault")
aqui el metodo "new" recibe 3 parametros:
"CARRO", 50, "renault"
2. $x->acelerar(7);
aqui el metodo "acelarar" recibe 2 parametro:
$x, 7
donde $x es una referencia a un objeto "CARRO"
cualquier metodo se puede llamarse de las 2 maneras... aunque lo usual
es que un metodo se llame con una de las 2 formas
1. cuando el metodo se llama como CARRO->new se dice
que es un metodo de clase... osea que no esta asociada a
un objeto especifico... aqui "new" es un metodo de clase
2. cuando el metodo se llama como $x->acelarar se dice
que es un metodo de instancia... osea que esta asociada a un objeto
... aqui "acelarar" es un metodo de instancia
tambien existen variables de clase y variables de instancia...
el modulo CGI
este modulo se usa para leer los campos de una forma enviada desde el Netscape
al apache y desde el apache a nuestro programa
use CGI;
$q = new CGI;
# $q es una referencia tipo CGI...
$ope = $q->param ('ope');
$cod = $q->param ('cod');
$cla = $q->param ('cla');
# param es una funcion de CGI que nos da el valor de un campo...
# practicamente no se necesita mas...
el modulo DBI
este modulo se usa para accesar una base de datos como ORACLE...
bueno hay otro modulo involucrado, DBD::Oracle, pero de eso es automatico...
ejemplo de una operacion de consulta
use DBI;
$dbh = DBI->connect('dbi:Oracle:', 'useru', 'clave' );
# $dbh es una referencia a un objeto...
# clase DBI::db... que no interesa...
$sth = $dbh->prepare ("select codemp, nomemp, vinemp from emp where ciaemp=?");
# esto hace que Oracle compile el "select"...
# $sth es una referencia un objeto de otra clase...
# clase DBI::st... que tampoco interesa...
$cia = <>;
# lea $cia del STDIN
$sth->execute ( $cia ) ;
# esto crea el cursor
while ( ($cod, $nom, $vin ) = $sth->fetchrow_array )
{
# aqui se lee el cursor
printf "%5s %30s %3s", $cod, $nom, $vin ;
}
$sth->finish;
# esto cierra el cursor
ejemplo de una operacion de actualizacion
use DBI;
$dbh = DBI->connect('dbi:Oracle:', 'useru', 'clave' );
$sth = $dbh->prepare ("delete from emp where ciaemp=?");
$sth->execute ( $cia ) ;
$dbh->commmit;
el prepare y execute se pueden hacer simultaneamente con do...
pero "prepare" permite utilizar "placeholders" (osea las interrogaciones)
que se llenan en el "execute"...
informacion del resultado de un prepare o execute
$DBI::err
# numero del error... analogo al sqlcode...
# es falso (no definido) si no hay error
$DBI::errstr
# texto del error
# es falso (no definido) si no hay error
informacion que se puede obtener despues del execute
$DBI::rows
# nro de filas afectadas... puede ser 0
# sirve tanto para consultas como actualizaciones
informacion que se puede obtener despues del execute de un select
$sth->{NAME}
# referencia al arreglo de los nombres de la columnas
# se puede usar aunque no se seleccione ninguna fila
$sth->{TYPE}
# referencia al arreglo de los tipos de los campos
$sth->{SCALE}
# referencia al arreglo de longitudes de los campos
algo mas...
mas sobre achivos
pipes...
open f1, "ps -xlw |";
# ejecutar el comando ps -xlw para leer su respuesta
# usando el descriptor f1
while ( <f1> )
{
print if /httpd/ ;
# selecciona los demonios de httpd
}
el operador diamante sin descriptor, osea <>, tiene un significado especial...
lee los archivos que se escribieron en la linea de comando donde se ejecuto
el programa perl... cuando se termina un archivo empata con el siguiente...
es bueno aclarar que perl coloca los argumentos que se dieron en la linea
de comando en el arreglo @ARGV...
si @ARGV no existe, <> lee del STDIN... o por supuesto el
archivo despues del "<" en la linea de comando... osea la redireccion
de STDIN...
como todo se puede en perl... @ARGV puede ser alterado dentro del programa...
@ARGV = ( "auxytd.98.3");
@a = <>;
# @a tiene todo el archivo
la funcion binmode para manejar archivos binarios...
osea que no tiene lineas terminadas en "\n"
open ( FX, "auxytd.bin" );
binmode ( FX );
# avisa a perl que se olvide del "\n"
read ( FX, $buffer, 100, 0 );
# lee hasta 100 bytes
la funcion select
cambia el descriptor default de print y write
y devuelve el viejo descriptor
open ( F2, ">abc.dou");
$old = select ( F2 );
# $old contiene a STDOUT
print "abcdef";
# imprime en el archivo "abc.dou"
select ( $old );
# todo regresa a la normalidad
el desriptor DATA se refiere a todo los que tiene el archivo del programa
despues de la linea __END__ ...
antes de la linea __END__ esta el programa perl...
por supuesto que la linea __END__ es opcional...
Perl tambien tiene los here documents de los shell de unix...
los here documents se utilizan cuando se requiere un string de muchas lineas...
$x = << "ETX";
linea 1
linea 2
ETX
$x queda con: linea 1\nlinea2\n
ETX es cualquier palabra... $x queda con todas las lineas antes
de la linea que tiene solo la palabra ETX...
osea que si no se coloca ETX en una linea $x se traga todo
el resto del archivo...
ojo! no olvide el ; despues de "ETX" al declarar el "here document"...
como se procesa un programa perl
perl procesa el programa en varias fases:
1. examina la linea #!/usr/bin/perl... buscando suiches...
este paso lo hace el shell de unix pero en W95/NT lo hace el perl
2. ejecucion previa... un recuerdo de awk...
subrutinas BEGIN...
funciones "use" para cargar modulos
recuerde que los modulos empiezan por mayuscula...
esta ejecucion tenprana de "use" es otra diferencia con "requiere"
... requiere se ejecuta en la fase 4
funciones "use" para dar directivas al compilador
en este caso la palabra que sigue a use empieza por minuscula
use integer;
# indica al compilador que solo queremos enteros
no integer;
# indica al compilador que queremos numeros decimales
3. compilacion... se habia dicho que perl no necesita compilar...
esta es una compilacion a un codigo intermedio no a codigo de maquina
...cancela si hay errores de sintaxis...
4. ejecucion carnuda...
ejecuta el codigo intermedio... hasta encontrar exit
... o hasta que se acabe el archivo... o hasta que encuentre
una linea con __END__
5. ejecucion final...otro recuerdo de awk...
subrutinas END... empezando por el ultimo que se cargo
en las subrutinas BEGIN y END se puede omitir sub
BEGIN {
print "esto se escribe en la fase 2\n";
print "aunque el programa tenga errores de sintaxis\n"
}
END {
print "esto se escribe en la fase 5\n";
print "despues que el programa termina \n"
}
print "esto se escribe en la fase 4 \n"";
la linea de comando de perl
perl se puede ejecutar con muchos suiches... algunos de estos suiches tambien se
pueden colocar en la linea "shebang" del programa... la que empieza por #!...
la primera linea del shell podria ser
#!/usr/bin/perl -w
la linea de conmando de perl puede ser
perl -v
# da la version de perl
perl -V
# muestra informacion sobre como se compilo el perl...
# al final muestra @INC que es otra e las variables especiales
# de perl
# @INC tiene los directorios donde perl busca los modulos
# y las librerias que se invocan con "use" y "requiere"
perl -w 0010.pl
# muestra warnings... muy util...
perl -d 0010.pl
# corre el programa en camara lenta... si se quiere...
# ejecuta el programa bajo el perl degugger
perl -e '....'
# ejecuta un programa entre comillas
# observe que no hay archivo de programa
perl -e '@a=(1..5); print "@a \n"'
# imprime: 1 2 3 4 5
el parametro -e acompa#ado de otros parametros se vuelve mas util
perl -n -e 's/pacho/francisco/; print' abc.txt
esto equivale al siguiente programa
while ( <> )
{
s/pacho/francisco/; print;
}
donde <> toma archivos de @ARGV... en este caso ("abc.txt")
... recuerde el operador diamante
cambiando -n por -p nos ahorramos escribir el print
perl -p -e 's/pacho/francisco/' abc.txt
esto eqivale a el siguiente programa
while ( <> )
{
s/pacho/francisco/;
print;
}
agregando -i podemos modificar el archivo abc.txt
perl -i.old -p -e 's/pacho/francisco/' abc.txt
remienda abc.txt y deja el archivo viejo como abc.txt.old
mas sobre contexto
la funcion wantarray usada dentro de una subrutina
devuelve 1 si el llamador de la subrutina desea un "contexto lista"...
sub fun
{
wantarray ? (1..5): 7;
}
$a = fun; # $a queda con 7
@a = fun; # @a queda con (1..5)
herencia de objetos
la herencia es un concepto muy importante en la teoria de objetos...
se supone que uno debe hacer un objeto complicado heredando de otros objetos mas simples...
p.e si alguien ha creado ya la clase VEHICULO uno podria empezar
la clase CARRO diciendo que se deriva de VEHICULO... osea que las propiedades
y metodos de VEHICULO se aprovechan para definir la clase CARRO... o tambien que
CARRO hereda de VEHICULO... es una herencia espiritual... varias clases pueden
heredar de VEHICULO...
el arreglo @ISA le indica a perl que si se invoca un metodo que no esta en el
paquete lo puede buscar tambien en los paquetes mencionados en el arreglo @ISA...
el ejemplo que sigue tiene 3 archivos.
1. archivo VEHICULO.pm
package VEHICULO;
sub funp1
{
print "funp1 recibe @_";
}
return 1;
2. archivo CARRO.pm
package CARRO;
@ISA = ( VEHICULO );
sub func1
{
$x = funp1 ( "xxx") ;
# gracias a @ISA se invoca VEHICULO->funp1
}
return 1;
3. archivo 0010.pl
use CARRO;
package main;
CARRO->func1 (xxx) ;
# imprime: funp1 recibe CARRO xxx
# aqui podemos decir que CARRO hereda de VEHICULO...
# o que CARRO se deriva de VEHICULO
# los archivos 1 y 2 deben colocarse en alguno de los directorios
# de @INC... o podemos poner un bloque BEGIN que agregue nuestro directorio
# a @INC... recuerde perl -V
BEGIN
{
unshift @INC, "/appl/pd";
}
@ISA tiene un miembro automatico llamado UNIVERSAL... todo los modulo heredan
automaticamente del modulo UNIVERAL...
si CARRO invoca un metodo que no esta en CARRO ni en VEHICULO se busca en
el paquete UNIVERSAL... y si el metodo todvia no se encuentra se busca un metodo comodin
llamado AUTOLOAD... primero en CARRO... luego en VEHICULO... y finalmente en UNIVERSAL...
su realimentacion
por supuesto que me gustaria oir sus criticas o sugerencias...
email: cjara@epq.com.co