Spec-Zone.ru › Perl 5.30

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.28.3/perldbmfilter

Spec-Zone.ru

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