NAME
perldbmfilter - Filtros DBM de Perl
SINOPSIS
$db = tie %hash, 'DBM', ...
$filtro_anterior = $db->filter_store_key ( sub { ... } );
$filtro_anterior = $db->filter_store_value( sub { ... } );
$filtro_anterior = $db->filter_fetch_key ( sub { ... } );
$filtro_anterior = $db->filter_fetch_value( sub { ... } );
DESCRIPCIÓN
Los cuatro métodos filter_*
mostrados arriba están disponibles en todos los módulos DBM incluidos en Perl: DB_File, GDBM_File, NDBM_File, ODBM_File y SDBM_File.
Todos los métodos funcionan de la misma manera y se usan para instalar (o desinstalar) un filtro DBM individual. La única diferencia entre ellos es el lugar en el que se instala el filtro.
Su funcionamiento se puede resumir de la siguiente manera:
- filter_store_key
-
Si se ha instalado un filtro con este método, se invocará cada vez que se escriba una clave en una base de datos DBM.
- filter_store_value
-
Si se ha instalado un filtro con este método, se invocará cada vez que se escriba un valor en una base de datos DBM.
- filter_fetch_key
-
Si se ha instalado un filtro con este método, se invocará cada vez que se lea una clave de una base de datos DBM.
- filter_fetch_value
-
Si se ha instalado un filtro con este método, se invocará cada vez que se lea un valor de una base de datos DBM.
Puede usar cualquier combinación de estos métodos (desde ninguno hasta los cuatro).
Todos los métodos de filtro devuelven el filtro, si existe; de lo contrario, devuelven undef
.
Para eliminar un filtro debe pasarle undef
.
El filtro
Cuando Perl llama a uno de estos filtros, una copia local de $_
contendrá la clave o el valor que se va a filtrar. El filtrado se realiza modificando el contenido de $_
. Se omite el código de retorno del filtro.
Ejemplo: el problema de la terminación de cadenas con un carácter NULL
Los filtros DBM son útiles para un tipo de problema en el que se desea aplicar siempre la misma transformación a todas las claves, a todos los valores, o a todas las claves y todos los valores.
Por ejemplo, considere el siguiente escenario. Tiene una base de datos DBM que desea compartir con una aplicación en C de terceros. La aplicación en C supone que todas las claves y sus valores correspondientes terminan con un carácter NULL. Sin embargo, Perl no usa el carácter de terminación NULL al escribir en bases de datos DBM, por lo que la aplicación Perl deberá encargarse de agregar la terminación NULL. Para escribir en la base de datos debe usar una instrucción similar a la siguiente:
$hash{"$clave\0"} = "$valor\0";
También hay que tener en cuenta el carácter NULL al determinar la longitud de claves y valores existentes.
Sería mucho mejor poder ignorar el problema de los caracteres NULL de terminación de cadena en el código principal de la aplicación y disponer de un mecanismo que agregue automáticamente un carácter NULL de terminación a todas las claves y todos los valores que se escriban en la base de datos, y lo elimine al leer de la base de datos. Como ya se habrá imaginado, éste es un problema que se puede solucionar fácilmente con filtros DBM.
use strict;
use warnings;
use SDBM_File;
use Fcntl;
my %hash;
my $archivo = "filt";
unlink $archivo;
my $db = tie(%hash, 'SDBM_File', $archivo, O_RDWR|O_CREAT, 0640)
or die "No se puede abrir $archivo: $!\n";
# Instalar filtros DBM
$db->filter_fetch_key ( sub { s/\0$// } );
$db->filter_store_key ( sub { $_ .= "\0" } );
$db->filter_fetch_value(
sub { no warnings 'uninitialized'; s/\0$// } );
$db->filter_store_value( sub { $_ .= "\0" } );
$hash{"abc"} = "def";
my $a = $hash{"ABC"};
# ...
undef $db;
untie %hash;
El código anterior usa SDBM_File, pero funcionará igual con todos los módulos DBM.
El contenido de cada filtro debe ser autodescriptivo. Los dos filtros "fetch" quitan el carácter NULL de terminación y los dos filtros "store" agregan un carácter NULL de terminación.
Otro ejemplo: las claves son enteros de C
Otro ejemplo del mundo real: de manera predeterminada, cuando Perl escribe en una base de datos DBM, siempre escribe la clave y el valor como cadenas. Así, cuando se ejecuta la siguiente instrucción:
$hash{12345} = "algo";
la clave 12345 se almacenará en la base de datos DBM como una cadena de 5 bytes, "12345". Si desea almacenarla como un entero de C, debe usar pack
al escribir y unpack
al leer.
El siguiente filtro DBM hace esto:
use strict;
use warnings;
use DB_File;
my %hash;
my $archivo = "filt";
unlink $archivo;
my $db = tie %hash, 'DB_File', $archivo, O_CREAT|O_RDWR, 0666,
$DB_HASH or die "No se puede abrir $archivo: $!\n";
$db->filter_fetch_key ( sub { $_ = unpack("i", $_) } );
$db->filter_store_key ( sub { $_ = pack ("i", $_) } );
$hash{123} = "def";
# ...
undef $db;
untie %hash;
El código anterior usa DB_File, pero funcionará con cualquiera de los módulos DBM.
En este caso no se han utilizado más que dos filtros; solo hay que manipular el contenido de la clave, por lo que no es necesario instalar ningún filtro de valores.
VEA TAMBIÉN
DB_File, GDBM_File, NDBM_File, ODBM_File y SDBM_File.
AUTOR
Paul Marquess
TRADUCTORES
Joaquín Ferrero (Tech Lead)
Enrique Nell (Language Lead)