The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NOMBRE

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)