5.18.1

名前

perldbmfilter - Perl DBM Filters

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

説明

The four filter_* methods shown above are available in all the DBM modules that ship with Perl, namely DB_File, GDBM_File, NDBM_File, ODBM_File and SDBM_File.

上述の四つの filter_* メソッドは、Perl と共に出荷されている全ての DBM モジュール、つまり DB_File, GDBM_File, NDBM_File, ODBM_File, SDBM_File で利用可能です。

Each of the methods works identically, and is used to install (or uninstall) a single DBM Filter. The only difference between them is the place that the filter is installed.

それぞれのメソッドは全く同じように動作し、一つの DBM フィルタの インストール(またはアンインストール)のために使われます。 これらの唯一の違いはフィルタをインストールする場所です。

To summarise:

要約すると:

filter_store_key

If a filter has been installed with this method, it will be invoked every time you write a key to a DBM database.

フィルタがこのメソッドにインストールされると、DBM データベースにキーを 書き込む毎に起動されます。

filter_store_value

If a filter has been installed with this method, it will be invoked every time you write a value to a DBM database.

フィルタがこのメソッドにインストールされると、DBM データベースに値を 書き込む毎に起動されます。

filter_fetch_key

If a filter has been installed with this method, it will be invoked every time you read a key from a DBM database.

フィルタがこのメソッドにインストールされると、DBM データベースからキーを 読み込む毎に起動されます。

filter_fetch_value

If a filter has been installed with this method, it will be invoked every time you read a value from a DBM database.

フィルタがこのメソッドにインストールされると、DBM データベースから値を 読み込む毎に起動されます。

You can use any combination of the methods from none to all four.

これらのメソッドは 0 個から 4 個全てまで好きな組み合わせで使えます。

All filter methods return the existing filter, if present, or undef if not.

全てのフィルタメソッドはもしあれば既に登録されているフィルタを、 なければ undef を返します。

To delete a filter pass undef to it.

フィルタを削除するには undef を渡します。

フィルタ

When each filter is called by Perl, a local copy of $_ will contain the key or value to be filtered. Filtering is achieved by modifying the contents of $_. The return code from the filter is ignored.

それぞれのフィルタが Perl によって呼び出されると、$_ のローカルコピーには フィルタされるキーや値が入ります。 フィルタリングは $_ の内容を変更することによって行われます。 フィルタからの返り値は無視されます。

例: NULL 終端問題

DBM Filters are useful for a class of problems where you always want to make the same transformation to all keys, all values or both.

全てのキー、全ての値、あるいはその両方に対して同じ変換を 常に 行いたいような問題の種類には DBM フィルタが便利です。

For example, consider the following scenario. You have a DBM database that you need to share with a third-party C application. The C application assumes that all keys and values are NULL terminated. Unfortunately when Perl writes to DBM databases it doesn't use NULL termination, so your Perl application will have to manage NULL termination itself. When you write to the database you will have to use something like this:

例えば、以下のようなシナリオを考えます。 サードパーティ C アプリケーションと共有する必要がある DBM データベースが あります。 C アプリケーションは 全ての キーと値が NULL 終端されていることを 仮定しています。 残念ながら Perl が DBM データベースに書き込むときには NULL 終端しないので、 Perl アプリケーションは自分自身で NULL 終端を管理する必要があります。 データベースに書き込むときに、以下のようなことをする必要があります:

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

Similarly the NULL needs to be taken into account when you are considering the length of existing keys/values.

同様に、すでにあるキーや値の長さを考慮するときには NULL を計算に入れる 必要があります。

It would be much better if you could ignore the NULL terminations issue in the main application code and have a mechanism that automatically added the terminating NULL to all keys and values whenever you write to the database and have them removed when you read from the database. As I'm sure you have already guessed, this is a problem that DBM Filters can fix very easily.

メインアプリケーションのコードでは NULL 終端問題を無視して、 データベースに書き込むときには自動的に終端の NULL を追加して、 データベースから読み込むときには自動的に削除する機構があれば とても便利です。 既に想像はしていると思いますが、これは 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;

The code above uses SDBM_File, but it will work with any of the DBM modules.

上述のコードでは SDBM_File を使っていますが、いずれの DBM モジュールでも 動作します。

Hopefully the contents of each of the filters should be self-explanatory. Both "fetch" filters remove the terminating NULL, and both "store" filters add a terminating NULL.

出来れば、それぞれのフィルタの内容は自己説明的であるべきです。 両方の "fetch" フィルタは終端の NULL を削除し、両方の "store" フィルタは 終端する NULL を追加します。

もう一つの例: キーは C の int

Here is another real-life example. By default, whenever Perl writes to a DBM database it always writes the key and value as strings. So when you use this:

もう一つの実際の生活の例です。 デフォルトでは、Perl が DBM データベースに書き込むときはいつでも、 キーと値を文字列として書き込みます。 従って、以下のように使うと:

    $hash{12345} = "something";

the key 12345 will get stored in the DBM database as the 5 byte string "12345". If you actually want the key to be stored in the DBM database as a C int, you will have to use pack when writing, and unpack when reading.

キー 12345 は、5 バイトの文字列 "12345" として DBM データベースとして 保管されます。 実際に DBM データベースに C の int としてキーを保管したい場合は、 書き込むときに pack を使い、読み込むときに unpack を使う 必要があります。

Here is a DBM Filter that does it:

以下はこのために 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;

The code above uses DB_File, but again it will work with any of the DBM modules.

上述のコードでは DB_File を使っていますが、いずれの DBM モジュールでも 動作します。

This time only two filters have been used; we only need to manipulate the contents of the key, so it wasn't necessary to install any value filters.

今回は二つのフィルタだけを使っています; キーの内容だけを操作する 必要があるので、値フィルタをインストールする必要はありませんでした。

SEE ALSO

DB_File, GDBM_File, NDBM_File, ODBM_File, SDBM_File

作者

Paul Marquess