Es posible añadir un filtro que procese los accesos a un DBM. Podemos definir una subrutina que es llamada cada vez que almacenamos un valor en el hash DBM y otra que sea llamada cada vez que se lee una entrada del hash DBM.
El formato general de uso es:
$db = tie %hash, 'DBM', ...
$old_filter = $db->filter_store_key ( sub { ... } );
$old_filter = $db->filter_store_value( sub { ... } );
$old_filter = $db->filter_fetch_key ( sub { ... } );
$old_filter = $db->filter_fetch_value( sub { ... } );
Usando estos filtros podemos serializar valores del hash que sean estructuras de datos complejas.
En el siguiente código el hash DBM %h contiene como valores referencias a
cadenas. El filtro vuelca con Data::Dumper el valor complejo y lo comprime
usando la función compress del módulo Compress::Zlib .
El proceso inverso consiste en descomprimir y evaluar:
$ cat -n dbwithfilter.pl
1 #!/usr/bin/perl
2 use warnings;
3 use Compress::Zlib;
4 use DB_File;
5 use Data::Dumper;
6
7 unlink 'mldbmtest.dat';
8
9 $h = tie my %db1, 'DB_File', 'mldbmtest.dat', O_CREAT | O_RDWR, 0666
10 or die "No se pudo inicializar el fichero MLDBM: $!\n";
11
12 $h->filter_store_value(sub { $_ = compress(Dumper($_)) });
13 $h->filter_fetch_value(sub { $_ = eval(uncompress($_)) });
14
15 %db1 = (
16 'alu2511' => [ 'a'x30 ],
17 'alu2233' => [ 'b'x30 ]
18 );
19
20 print Data::Dumper->Dump( [ \%db1 ] );
Este otro programa lee el hash DBM creado por el programa anterior:
$ cat -n dbwithfilterretrieve.pl
1 #!/usr/bin/perl
2 use warnings;
3 use Compress::Zlib;
4 use DB_File;
5 use Data::Dumper;
6
7 my $h = tie my %db2, 'DB_File', 'mldbmtest.dat', O_RDWR, 0666
8 or die "No se pudo leer el fichero MLDBM: $!\n";
9 $h->filter_store_value(sub { $_ = compress(Dumper($_)) });
10 $h->filter_fetch_value(sub { $_ = eval(uncompress($_)) });
11
12 print Data::Dumper->Dump( [ \%db2 ] );
Cuando se ejecutan estos dos programas obtenemos la siguiente salida:
$ dbwithfilter.pl
$VAR1 = {
'alu2233' => [ 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' ],
'alu2511' => [ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' ]
};
lhp@nereida:~/Lperl/src$ dbwithfilterretrieve.pl
$VAR1 = {
'alu2233' => [ 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' ],
'alu2511' => [ 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' ]
};
Casiano Rodríguez León
