Hashes DBM

Cuando Perl se instala en un sistema proporciona una pasarela a las librerías C que dan soporte a DBM (y a la librería SDBM que se encuentra en la distribución de Perl).

Las DBM tienen una limitación: sólo se pueden almacenar pares clave-valor escalares. No es posible almacenar estructuras de datos complejas.

La función dbmopen

La función dbmopen nos permite crear hashes persistentes. Veamos el siguiente ejemplo dbm.pl que utiliza un hash DBM para almacenar una gramática:

lhp@nereida:~/Lperl/src$ cat -n dbm.pl
 1  #!/usr/bin/perl -w
 2  use strict;
 3  my %DATA;
 4
 5  dbmopen(%DATA, "my_gramma", 0644) or die "can not create my_gramma $!";
 6  $DATA{TOKENS} = "+|-|/|*|(|)|num";
 7  $DATA{START} = "E";
 8  $DATA{E} = "E+T|E-T";
 9  $DATA{T} = "T*F|T/F";
10  $DATA{F} = "(E)|num";

$DATA{TOKENS} contiene los terminales de la gramática, $DATA{START} el símbolo de arranque y $DATA{A} contiene las reglas de producción de la variable sintáctica A.

Antes de la ejecución de dbm.pl tenemos dos programas Perl dbm.pl y dbm2.pl en nuestro directorio:

>ls -l
-rwxrwx--x    1 pl       users         194 Mar 10 08:44 dbm.pl
-rwxrwx--x    1 pl       users         300 Mar 10 09:54 dbm2.pl

Después de la ejecución de dbm.pl aparecen dos nuevos ficheros que contienen las claves y valores del hash persistente:

>ls -l
-rwxrwx--x    1 pl       users         194 Mar 10 08:44 dbm.pl
-rwxrwx--x    1 pl       users         300 Mar 10 09:54 dbm2.pl
-rw-r-----    2 pl       users       12333 Mar 10 10:54 my_gramma.pag
-rw-r-----    2 pl       users       12333 Mar 10 10:54 my_gramma.dir

Veamos ahora otro programa que usa el hash persistente:

lhp@nereida:~/Lperl/src$ cat -n dbm2.pl
 1  #!/usr/bin/perl -w
 2  use strict;
 3  my %G;
 4  dbmopen(%G, "my_gramma", 0644) or die "can not create my_gramma $!";
 5
 6  my $tokens = $G{TOKENS};
 7  my @tokens = split('\|',$tokens);
 8
 9  print "TOKENS: ";
10  {
11    local $" = ',';
12    print "@tokens\n";
13  }
14
15  my $start = $G{START};
16  print "$start -> $G{$start}\n";
17
18  for my $k (sort keys %G) {
19    print "$k -> $G{$k}\n" if ($k !~ /(START)|(TOKENS)|($start)/);
20  }
Al ejecutarlo obtenemos esta salida:

> dbm2.pl
TOKENS: +,-,/,*,(,),num
E -> E+T|E-T
F -> (E)|num
T -> T*F|T/F

El Módulo DB_File

Una alternativa a dbmopen es usar el módulo DB_File. El siguiente ejemplo muestra como usarlo:

$ cat -n testdbfile.pl
 1  #!/usr/local/bin/perl -w
 2  use strict;
 3  use DB_File;
 4  my $file = shift || 'test';
 5  my %h;
 6  tie (%h, 'DB_File', $file) or die $!;
 7
 8  $h{abc} = "ABC"; $h{def} = "DEF"; $h{ghi} = "GHI";
 9  untie (%h);
10
11  my %g;
12  tie (%g, 'DB_File', $file) or die $!;
13
14  print "$_ => $g{$_}\n" for keys %g;
15
16  untie(%g);

al ejecutar se obtiene:

$ testdbfile.pl
abc => ABC
ghi => GHI
def => DEF



Subsecciones
Casiano Rodríguez León
2009-10-04