Spec-Zone.ru › Perl 5.38

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 v5.36;
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.

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

Другой пример: ключ — C-целое.

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

$hash{12345} = "something";

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

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

use v5.36;
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–2023 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.38.0/perldbmfilter

Spec-Zone.ru

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