Perl

Misosguar
Diego Rubens Mañas

Cuál es el operador Módulo?

El símbolo % es el operador módulo que retorna el residuo de la división entre dos enteros. Si sumamos una unidad a una variable y calculamos su módulo n, en algún momento el resultado será cero


my $i= 0;
warn $i;
$i= ($i + 1) % 4;
warn $i;
$i= ($i + 1) % 4;
warn $i;
$i= ($i + 1) % 4;
warn $i;
$i= ($i + 1) % 4;
warn $i;
$i= ($i + 1) % 4;
warn $i;
$i= ($i + 1) % 4;
warn $i;
$i= ($i + 1) % 4;
warn $i;
$i= ($i + 1) % 4;
warn $i;

La salida es:

0
1
2
3
0
1
2
3
0
tags: operador

Un hash se declara con llaves?

La llave se usa para acceder a un valor de un hash a través de su clave. Un hash literal se escribe entre paréntesis separando la clave del valor con el símbolo =>


my %agrupacion= (4=>4,3=>4,7=>5);
warn $agrupacion{3};

La salida es:

4
tags: hash

Si la llave es 0 su consulta es false?

Cuando la llave de un hash no existe o vale 0 su consulta produce false


my $elegido = {};
if ($elegido->{'pepe'}){ warn 'elegido Pepe'; }
else{ 
   $elegido->{'pepe'} = 1; 
   warn 'nuevo Pepe'; 
}

$elegido->{'pepo'} = 0;

if ($elegido->{'pepe'}){ warn 'elegido Pepe'; }
else{ 
   $elegido->{'pepe'} = 1; 
   warn 'nuevo Pepe'; 
}

if ($elegido->{'pepo'}){ warn 'elegido Pepo'; }
else{ 
   $elegido->{'pepo'} = 1; 
   warn 'nuevo Pepo'; 
}

La salida es:

nuevo Pepe 
elegido Pepe 
nuevo Pepo
tags: hash

Usar @ o $?

Cuando usamos una referencia a un array y queremos acceder a un elemento debemos indicar que la referencia es un array usando @$. Un mensaje de error podría ser "pop on reference is experimental" indicando que falta el símbolo @


# referencia a un array vacío
my $listado= [];
# referencia a un array de arrays
my $VAR1 = [
          [
            '1',
            '47786850',
            'Sin llamar',
            '#ffee'
          ],
          [
            '2',
            '47786851',
            'Sin llamar',
            '#ff33'
          ],
          [
            '3',
            '47786852',
            'Sin llamar',
            '#09fa'
          ]
        ];
# usar @ o $
my $np= pop(@$VAR1);
# usar @ o $
push(@$listado,$np);
# usar @ o $
$np= pop(@$VAR1);
push($listado,$np);
print Dumper($np);
print Dumper($listado);

La salida es:

$np = [
          '2',
          '47786851',
          'Sin llamar',
          '#ff33'
        ];
$listado = [
          [
            '3',
            '47786852',
            'Sin llamar',
            '#09fa'
          ],
          [
            '2',
            '47786851',
            'Sin llamar',
            '#ff33'
          ]
        ];
tags: array ref

Referencia a un array o array literal?

Una lista de valores encerrados entre corchetes es una referencia a un array. Por eso en el ejemplo siguiente muestra que $a es un ref array y $b no está definido. Una lista de valores entre paréntesis es un array y puede asignarse a una variable de tipo array o a una lista de variables, como $e y $c en el ejemplo siguiente:


my ($a,$b)= [1,'o'];
warn $a;
warn $b;
my ($e,$c)= (1,'o');
warn $e;
warn $c;
warn 'fin';

La salida es:

ARRAY(0x1edaf30)
Warning: something's wrong
1 
o 
fin
tags: ref

Efecto de push y shift simula una cola?

En un array, push coloca los datos al final, y shift los saca de adelante. Ambos modifican el array


my @cola = (1,3,5,8);
push(@cola,2);
push(@cola,11);
push(@cola,9);
while(my $id= shift(@cola)){
   warn $id;
}

La salida es:

1
3
5
8
2
11
9
tags: array

Usar un valor aleatorio dentro de un rango?

Creamos un array con los valores de un rango de string entre '00' y '59'. Luego, como el array está indizado con un entero tomamos un valor aleatorio entero entre 0 y 60, el 60 está excluído. Con expresiones regulares sustituimos algunos caracteres por guión bajo. La probabilidad de que se repita el nombre es baja pero igualmente existe


sub make_file_name{
   my $telefono= shift;
   my $fechahora= shift;
   # valor aleatorio de milisegundos para no repetir nombre
   my $val_sup = 60;
   my $val_fin = '59';
   my @mili= ('00'..$val_fin);	
   my $nombre_grabacion= $fechahora . '_' . $mili[int(rand($val_sup))] . '_' . $telefono;
   # sustituir / por _
   $nombre_grabacion =~ s/\//_/g;
   # sustituir - por _
   $nombre_grabacion =~ s/\-/_/g;
   # sustituir espacio por _
   $nombre_grabacion =~ s/ /_/g;
   # sustituir : por _
   $nombre_grabacion =~ s/:/_/g;
   # sustituir . por _
   $nombre_grabacion =~ s/\./_/g;        
   
   return $nombre_grabacion;
}

warn make_file_name(3342342,'45-45-666- 0:00:10');
warn make_file_name(3342342,'45-45-666- 0:00:10');
warn make_file_name(3342342,'45-45-666- 0:00:10');
warn make_file_name(3342342,'45-45-666- 0:00:10');

La salida es:

45_45_666__0_00_10_09_3342342
45_45_666__0_00_10_19_3342342
45_45_666__0_00_10_49_3342342
45_45_666__0_00_10_25_3342342
tags: rand rango

Cómo verificar el último caracter de un string?

Con una expresión regular verificamos si el último carácter de un string no es el esperado. Como la barra es especial la escapamos con una barra invertida. El signo $ indica el final del string. Si no tiene la barra se la concatenamos con .=


my $canal = 'sip';
warn $canal;
if ($canal !~ /\/$/){ 
   warn 'falta poner /'; 
   $canal .= '/'; 
}
warn $canal;

La salida es:

sip
falta poner /
sip/
tags: regexp

Cómo verificar la existencia de dos caracteres en un string?

Con una expresión regular podemos verificar si un caracter está contenido en un string. Para buscar dos caracteres que podrían estar en cualquier posición podemos usar la misma expresión regular dos veces y unirlas con un AND. En ese caso la ocurrencia ocurre cuando ambos caracteres están en el string. Si sólo nos interesa saber si alguno de ellos está podemos usar corchetes, que buscan una coincidencia en un rango. Para saber cuál fue el caracter encontrado hacemos uso del paréntesis, como en el ejemplo de "julio"


my $junio= 'Local/0383277405302@default-000031ad;1';
my $julio= 'Remoto;23';
my $agosto= 'SIP/clientex-000073cc';
if ($junio=~/@/ && $junio=~/;/){ warn 'coincidencia junio'; }
if ($junio=~/[@;]/){ warn 'coincidencia 1 o más en junio'; }
if ($julio=~/@/ && $julio=~/;/){ warn 'coincidencia julio'; }
if ($julio=~/[@;]/){ warn 'coincidencia 1 o más en julio'; }
if ($julio=~/([@;])/){ warn "coincidencia $1 en julio"; }
if ($agosto=~/([@;])/){ warn 'coincidencia en agosto'; }

La salida es:

coincidencia junio
coincidencia 1 o más en junio
coincidencia 1 o más en julio
incidencia ; en julio
tags: regexp

Cómo extraer un prefijo de un número?

Con una expresión regular capturamos los dígitos que siguen al prefijo, si es que existe ese prefijo. El \d busca dígitos y el \d+ busca 1 o más dígitos. Con los paréntesis le indicamos que lo capture y lo guarde en nuestra variable


my $exten	= 991000;
warn "-- $exten ";
my $prefijo = 99;
my ($interno) = $exten=~/$prefijo(\d+)/;
warn "-- $interno ";

La salida es:

-- 991000
-- 1000
tags: regexp

Puedo tomar trozos de arrays?

Utilizando rangos en los índices de los arrays podemos asignar trozos de arrays y colocarlos en otro array


# asignar una lista a variables escalares
my ($i,$j,$no) = (4,5,12);
my ($cant_i,$cant_j) = ($i,$j);
# referencia a un array
my $a = [1 ,2, 3, 4, 5, 6, 7];
if ($i > @{$a}){ $cant_i =  @{$a}; }
# variable array
my @b = (11,22,33);
if ($j > @b){ $cant_j = @b; }
# referencia a array vacio
my $c = [];
# colocar en un array trozos de otros arrays
push (@{$c},@{$a}[0..$cant_i-1],@b[0..$cant_j-1]);
# usar Data::Dumper para mostrar el contenido de las variables
print Dumper($a);
print Dumper(\@b);
if ($i>@{$a}){
   # lo que falta lo saco de @b
   my $limite = @b;
   if ($limite > $cant_j + $i - $cant_i){ $limite= $cant_j + $i - $cant_i; }
   push(@{$c},@b[$cant_j..$limite-1]);
}elsif($j>@b){
   # lo que falta lo saco de @a
   my $limite= @{$a};
   if ($limite > $cant_i + $j - $cant_j){ $limite= $cant_i + $j - $cant_j; }
   push(@{$c},@{$a}[$cant_i..$limite-1]);
}
print Dumper($c);

La salida es:

   [
      1,
      2,
      3,
      4,
      11,
      22,
      33,
      5,
      6
   ];
tags: array rango