Spec-Zone.ru › Perl 5.32

perldbmfilter

СОДЕРЖАНИЕ

  • ИМЯ
  • СИНТАКСИС
  • ОПИСАНИЕ
    • Фильтр
    • Пример: проблема нулевого завершения.
    • Другой пример: ключ — целочисленная переменная C.
  • СМОТРИТЕ ТАКЖЕ
  • АВТОР

ИМЯ

perldbmfilter — Фильтры Perl DBM

СИНТАКСИС

$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 { ... } );

ОПИСАНИЕ

Четыре метода filter_* выше доступны во всех модулях DBM, поставляемых с Perl, а именно DB_File, GDBM_File, NDBM_File, ODBM_File и SDBM_File.

Каждый из методов работает одинаково и используется для установки (или отключения) одного фильтра DBM. Единственное различие между ними — место установки фильтра.

Вкратце:

filter_store_key

Если фильтр установлен с помощью этого метода, он будет вызываться каждый раз при записи ключа в базу данных DBM.

filter_store_value

Если фильтр установлен с помощью этого метода, он будет вызываться каждый раз при записи значения в базу данных DBM.

filter_fetch_key

Если фильтр установлен с помощью этого метода, он будет вызываться каждый раз при чтении ключа из базы данных DBM.

filter_fetch_value

Если фильтр установлен с помощью этого метода, он будет вызываться каждый раз при чтении значения из базы данных DBM.

Вы можете использовать любую комбинацию методов от нуля до всех четырех.

Все методы фильтров возвращают существующий фильтр, если он есть, или undef, если нет.

Чтобы удалить фильтр, передайте undef в него.

Фильтр

Когда Perl вызывает каждый фильтр, локальная копия $_ будет содержать ключ или значение, подлежащие фильтрации. Фильтрация достигается путем изменения содержимого $_. Код возврата фильтра игнорируется.

Пример: проблема нулевого завершения.

Фильтры DBM полезны для класса задач, где вы всегда хотите произвести одно и то же преобразование над всеми ключами, всеми значениями или обоими.

Например, рассмотрим следующую ситуацию. У вас есть база данных DBM, которую необходимо поделиться с приложением C от стороннего разработчика. Приложение C предполагает, что все ключи и значения имеют нулевое завершение. К сожалению, когда Perl записывает в базы данных DBM, он не использует нулевое завершение, поэтому вашему приложению Perl придется самостоятельно обрабатывать нулевое завершение. При записи в базу данных вам придется использовать что-то вроде этого:

$hash{"$key\0"} = "$value\0";

Аналогично, при рассмотрении длины существующих ключей/значений необходимо учитывать нули.

Гораздо лучше было бы игнорировать проблему нулевого завершения в основном коде приложения и иметь механизм, который автоматически добавлял бы завершающий ноль ко всем ключам и значениям при записи в базу данных и удалял их при чтении из базы данных. Как вы, наверное, уже догадались, эта проблема легко решается с помощью фильтров DBM.

use strict;
use warnings;
use SDBM_File;
use Fcntl;

my %hash;
my $filename = "filt";
unlink $filename;

my $db = tie(%hash, 'SDBM_File', $filename, O_RDWR|O_CREAT, 0640)
  or die "Cannot open $filename: $!\n";

# Install DBM Filters
$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;

В приведенном выше коде используется SDBM_File, но он будет работать с любым из модулей DBM.

Надеюсь, содержимое каждого фильтра должно быть понятным. Оба фильтра «чтения» удаляют завершающий ноль, а оба фильтра «записи» добавляют завершающий ноль.

Другой пример: ключ — целочисленная переменная C.

Вот еще один реальный пример. По умолчанию, когда Perl записывает в базу данных DBM, он всегда записывает ключ и значение как строки. Таким образом, когда вы используете это:

$hash{12345} = "something";

ключ 12345 будет сохранен в базе данных DBM как строка из 5 байтов "12345". Если вы хотите, чтобы ключ хранился в базе данных DBM как целая переменная C, вам придется использовать pack при записи и unpack при чтении.

Вот фильтр DBM, который это делает:

use strict;
use warnings;
use DB_File;
my %hash;
my $filename = "filt";
unlink $filename;


my $db = tie %hash, 'DB_File', $filename, O_CREAT|O_RDWR, 0666,
    $DB_HASH or die "Cannot open $filename: $!\n";

$db->filter_fetch_key  ( sub { $_ = unpack("i", $_) } );
$db->filter_store_key  ( sub { $_ = pack ("i", $_) } );
$hash{123} = "def";
# ...
undef $db;
untie %hash;

В приведенном выше коде используется DB_File, но, опять же, он будет работать с любым из модулей DBM.

В этот раз использовались только два фильтра; нам нужно было манипулировать только содержимым ключа, поэтому установка каких-либо фильтров для значений не была необходима.

СМОТРИТЕ ТАКЖЕ

DB_File, GDBM_File, NDBM_File, ODBM_File и SDBM_File.

АВТОР

Пол Маркесс

© 1993–2020 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.32.0/perldbmfilter

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API