by Hippo2000(2001/8/5)
日本語チョウ訳シリーズ AnyDataモジュールなのです。
いつものことですが、わかりにくい(あやしい)説明は本物を見てください。(^^;原本の著作権はJeff Zucker氏がお持ちです(詳しくは著作権情報を見てください)。Jeff Zucker氏にはメールで了解をいただきました。
内容等が間違っていたら修正します。ご連絡ください。
AnyDataのサブモジュール:
モジュール名 AnyData::Format::CSV CSVファイル用フォーマッタ AnyData::Format::Fixed 固定長レコード用フォーマッタ AnyData::Format::HTMLtable HTMLテーブル用フォーマッタ AnyData::Format::Ini Iniファイル用フォーマッタ AnyData::Format::Mp3 MP3ファイル用フォーマッタ AnyData::Format::Paragraph パラグラフ用フォーマッタ AnyData::Format::Passwd Passwdファイル用フォーマッタ AnyData::Format::Pipe パイプ区切りファイル用フォーマッタ AnyData::Format::Tab タブ区切りファイル用フォーマッタ AnyData::Format::Weblog HTTPDログファイル用フォーマッタ AnyData::Format::XML XML用フォーマッタ AnyData::Storage::File 警告が豊富なファイルの取り扱い
AnyData -- 多くのフォーマットのデータへの簡単なアクセス
$table = adTie( 'CSV','my_db.csv','o', # テーブルの作成
{col_names=>'name,country,sex'}
);
$table->{Sue} = {country=>'de',sex=>'f'}; # 行の挿入
delete $table->{Tom}; # 1つの行の削除
$str = $table->{Sue}->{country}; # 1つの値を選択
while ( my $row = each %$table ) { # テーブル全体のループ
print $row->{name} if $row->{sex} eq 'f';
}
$rows = $table->{{age=>'> 25'}} # 複数の行を選択
delete $table->{{country=>qr/us|mx|ca/}}; # 複数の行を削除
$table->{{country=>'Nz'}}={country=>'nz'}; # 複数の行を更新
my $num = adRows( $table, age=>'< 25' ); # マッチする行のカウント
my @names = adNames( $table ); # カラム名の取得
my @cars = adColumn( $table, 'cars' ); # カラムをまとめる
my @formats = adFormats(); # 利用できるパーサーのリスト
adExport( $table, $format, $file, $flags ); # 指定されたフォーマットで保存
print adExport( $table, $format, $flags ); # そのフォーマットで画面に表示
print adDump($table); # 画面にテーブルをダンプ
undef $table; # テーブルをクローズ
adConvert( $format1, $file1, $format2, $file2 ); # フォーマット間で変換
print adConvert( $format1, $file1, $format2 ); # 画面に変換
このモジュールとこの姉妹モジュールDBD::AnyDataの裏にあるwackyなアイデアは、ソースやフォーマットに関わらず、同じ簡単なメソッドのセットでアクセスしたり、変更することができるべきだということです。このモジュールは多次元の、数多くの異なるフォーマットのデータへのtieされたハッシュ・インターフェースを提供します。DBD::AnyDataモジュールはそれらの同じフォーマットのためのDBI/SQLインタフェースを追加しています。
どちらのモジュールもすべてのI/Oのための適切なflocking()、そして(ほとんどの場合)ファイル全体を取り込むのではなく、レコード毎のアクセスを含む組み込みの保護機能を提供します。
現在のところサポートされているフォーマットには汎用的なフォーマット・フラットファイル(CSV、固定長など)、特定のフォーマット(passwdファイル、httpdログなど)、そしてその他のフォーマットの種類の数々(XML、Mp3、HTMLテーブル)が含まれます。AnyDataそれ自身に組み込むことができ、そのためtieされたハッシュとDBI/SQLインタフェースのどちらからもアクセスすることができる追加のフォーマット・パーサーを作ることを簡単にするオープンなAPIがあるので、サポートされるフォーマットの数は増え続けます。
AnyData.pm モジュールそれ自身はpure Perlで、標準にPerlと一緒に入ってくるモジュール以外になにも依存していません。フォーマットあるいは高度な機能の中には追加のモジュールを必要とするものもあります:リモートのftp/http機能を使うためには、LWPバンドルをインストールしなければなりません;XMLフォーマットを使うには、XML::ParserとXML::Twigをインストールしなければなりません;HTMLテーブルフォーマットを読むためにはHTML::ParserとHTML::TableExtractをインストールする必要があります。しかしHTMLテーブルを出力するには標準のCGIモジュールだけで使うことができます。DBI/SQLコマンドを使うためには、DBI、DBD::AnyData、SQL::StatementそしてDBD::Fileをインストールしなければなりません。
AnyData モジュールは8つのメソッド(関数)をインポートします:
adTie() -- 新しいテーブルを作るか、既にあるテーブルを開く adExport() -- 既にあるテーブルを指定されたフォーマットで保存する adConvert() -- あるフォーマットから別のフォーマットにデータを変換する adFormats() -- 利用できるフォーマットのリスト adNames() -- テーブルのカラム名を取得 adRows() -- テーブルもしくは問い合わせの行の数を取得 adDump() -- 行の配列としてフォーマットされたデータを表示 adColumn() -- 1つのカラムに値をまとめる
adTie() コマンドは特殊なtieされたハッシュを返します。tieされたハッシュは データをアクセスそして/あるいは変更するために使うことができます。詳細は下記をご覧ください。 XML、HTMLテーブルそして配列フォーマットを除いて、adTie()コマンドは変更されると そのときに直接ファイルにすべての変更を保存します。 XMLとHTMLテーブルではメモリ上で変更し、明示的にadExport()でファイルに保存しなければなりません。
my $table = adTie( $format, $data, $open_mode, $flags );
adTie()コマンドは多次元のtieされたハッシュへのリファレンスを作成します。このとても簡単な形式では、単にファイルを指定されたフォーマットでtieされたハッシュに読み込みます:
my $table = adTie( $format, $file );
$formatはサポートされているフォーマットの名前 'CSV'、'Fixed'、'Passwd'などです。
$fileはローカル・ファイルへの相対または絶対パス名です。
e.g. my $table = adTie( 'CSV', '/usr/me/myfile.csv' );
これはファイル'myfile.csv'からCSV(カンマ区切り(=comma separated values))
フォーマットでデータを読み込むことにより、$tableというtieされたハッシュを作成します。adTie()からの結果のハッシュ・リファレンスは以下のようにアクセス、変更することができます:
use AnyData;
my $table = adTie( $format, $file );
$table->{$key}->{$column} # 値の選択
$table->{$key} = {$col1=>$val1,$col2=>$val2...} # 行の更新
delete $table->{$key} # 行の削除
while(my $row = each %$table) { # 行全体のループ
print $row->{$col1} if $row->{$col2} ne 'baz';
}
adTieにより返されるもの(例では$table)はオブジェクトではなく、tieされたハッシュです。つまりexists、values、keysのようなハッシュ操作を使うことができるということです。これがtieされたハッシュへの*リファレンス*であることを忘れないでください。そのため書き方は以下のようになります:
for( keys %$table ) {...}
for( values %$table ) {...}
テーブルが本当に大きければ、おそらくkeysとvaluesを使いたくないでしょう、というのもそれらはテーブルの各行からのデータが入ったメモリ上に作るからです。代わりに上記のように'each'を使ってください。というのもそれはメモリにテーブル全体をおくのではなくファイル全体を通して1レコード毎に繰り返すからです。
ハッシュにより高度な検索をかけることも可能です。下記の"複数行の操作"をご覧ください。
簡単なadTime($format, $file)に加えて、adTie()コマンドで追加の情報を指定するほかの方法があります。全体の書き方は以下の通りです:
my $table = adTie( $format, $data, $open_mode, $flags );
$dataパラメータはhttpまたはftpでアクセスすることができるリモート・ファイルからデータを読むことが可能です。下記の"リモート・ファイル"をご覧ください。ファイルをまったく必要とせずに文字列や配列をデータとして扱うことも可能です。下記の"文字列や配列で動かす"をご覧ください。
オプションの$modeパラメータは何も与えられなければデフォルトは'r'です。以下のいずれかにしなければなりません
'r' read # 読み込みのみアクセス 'u' update # read/write アクセス 'c' create # ファイルがすでになければ新しいファイルを作成 'o' overwrite # すでにファイルがあれば上書きして、新しいファイルを作成
$flags パラメータによりカラム名のような追加の情報を指定することができます。下記のセクション"詳細情報"をご覧ください。
XML、HTMLtableそしてARRAYフォーマットの例外を除いて、adTie()コマンドはすべてのデータの変更を変更されたときに直接ファイルに保存します。XMLとHTMLtableでは、メモリ上で変更をおこない、adExport()で明示的にファイルに出力しなければなりません。
adConvert( $format1, $data1, $format2, $file2, $flags1, $flags2 ); または print adConvert( $format1, $data1, $format2, undef, $flags1, $flags2 ); または my $aryref = adConvert( $format1, $data1, 'ARRAY', undef, $flags1 );
このメソッドはサポートされているフォーマットのデータを他のサポートされているフォーマットに変換します。結果のデータは($file2がパラメータとして与えられれば)ファイルに保存されるか、($file2が与えられなければ)例えば画面に新しいフォーマットで出力するようなために文字列として返されるか、あるいは$format2が'ARRAY'であれば配列リファレンスとして返されます。
いくつかの例:
# CSV ファイルをXMLファイルに変換
#
adConvert('CSV','foo.csv','XML','foo.xml');
# CSVファイルをHTMLテーブルに変換し、画面に出力
#
print adConvert('CSV','foo.csv','HTMLtable');
# XML文字列をCSVファイルに変換
#
adConvert('XML', ["<x><motto id='perl'>TIMTOWTDI</motto></x>"],
'CSV','foo.csv'
);
# 配列リファレンスをXMLファイルに変換
#
adConvert('ARRAY', [['id','motto'],['perl','TIMTOWTDI']],
'XML','foo.xml'
);
# XMLファイルを配列リファレンスに変換
#
my $aryref = adConvert('XML','foo.xml','ARRAY');
詳細は下記の"文字列と配列を使う"をご覧ください。
adExport( $table, $format, $file, $flags ); または
print adExport( $table, $format ); または my $aryref = adExport( $table, 'ARRAY' );
このメソッドは既にあるtieされたハッシュを他のフォーマットに変換し、そして/またはtieされたハッシュを指定されたフォーマットでファイルに保存します。
いくつかの例: すべて先に my $table= adTie(...);が呼ばれているものとします # テーブルをXMLファイルにエクスポート # adExport($table','XML','foo.xml'); # テーブルをHTML文字列にエクスポートし、画面に出力 # print adExport($table,'HTMLtable'); # テーブルを配列リファレンスにエクスポート # my $aryref = adExport($table,'ARRAY');
詳細は下記の"文字列と配列を使う"をご覧ください。
my $table = adTie(...); my @column_names = adNames($table);
このメソッドは指定されたテーブルのためのカラム名の配列を返します。
my $table = adTie(...); adRows( $table, %search_hash );
このメソッドはadTie()で作成されたAnyDataのtieされたハッシュを取り、検索ハッシュ(search_hash)にマッチするテーブルの行を数えます。
例えば以下の簡単なスクリプトはrequestカラムに指定されたページが入っている、ファイルでの行の数を返します。
my $hits = adTie( 'Weblog', 'access.log'); print adRows( $hits , request => 'mypage.html' );
検索ハッシュ(search_hash)には複数の検索条件を入れることができます。下記のセクション"複数行の操作"をご覧ください。
検索ハッシュ(search_hash)が省略されると、すべての行の数を返します。
my @col_vals = adColumn( $table, $column_name, $distinct_flag );
このメソッドは指定されたカラムから値の配列を返します。もしdistinct_flagがあれば、重複はリストから削除されます。
例えば、以下の簡単なスクリプトはテーブルの'player'カラムでのユニークな値のリストを返します。
my $game = adTie( 'Pipe','games.db' ); my @players = adColumn( $game, 'player', 1 );
my $table = adTie(...); print adDump($table);
このメソッドはテーブルの生のデータを出力します。カラム名は鍵括弧の中に出力され、コロンで区切られ、最初の行に出力されます。そして各行は括弧の中の値のリストで出力されます。
print "$_\n for adFormats();
このメソッドは利用できるフォーマット・パーサ 例えば'CSV'、'XML'などを表します。これは../AnyData/Formatディレクトリを探すために@INCを見ます、そしてそこにあったフォーマット解析ファイルの名前を出力します。パーサーがさらにモジュールを必要とし(例えばXMLはXML::Parserを必要とします)、追加のモジュールをインストールしていなければ、このコマンドでリストされていても、そのフォーマットは動きません。そうでなければすべてのフォーマットはこのドキュメントで説明している通りに動くはずです。
カラム名は以下の3つの方法で決まります:
* pre -- フォーマット・パーサーがあらかじめカラム名を与えている
(例えば Passwd は自動的に'username','homedir', 'GID'などの
名前のカラムを持っています).
* user -- ユーザがキー'cols'で関連付けられたカンマ区切りの、
文字列でカラム名を指定する:
my $table = adTie( $format,
$file,
$mode,
{cols=>'name,age,gender'}
);
* auto -- あらかじめ決められたカラム名のリストがなく
ユーザが定義しなければ、ファイルの先頭行が
カラム名のリストとして扱われます;
その行は指定されたフォーマットに従って解析されます
(例えば CSV カラム命はカンマ区切りリスト、Tabカラム名
タブで区切られたリスト);
カラム名があらかじめ決まっていないフォーマットで新しいファイルを作るとき、ユーザは上記のようにして手動で設定*しなければなりません*。
いくつかのフォーマットはカラム名を代入するために特別な決まりを持っています(XML、Fixed、HTMLtables)。下記のそれらのフォーマットのセクションをご覧ください。
AnyDataモジュールはそのようなキーを持たないテーブルと同様に、各行をユニークに識別できる1つのキー・カラムを持っているテーブルをサポートしています。ユニーク・キーを持っているテーブルについては、キーは3つの方法で設定することができます:
* pre -- フォーマット・パーサーが自動的にあらかじめキー・カラム
を割り当てます。Passwdファイルは自動的に
キー・カラムとして'username'を持っています。
* user -- ユーザがキー・カラム名を指定します:
my $table = adTie( $format,
$file,
$mode,
{key=>'country'}
);
* auto 何もあらかじめ決まっているキー・カラムがなく、ユーザが定義
しなければ、最初のカラムがデフォルトのキー・カラムに
なります
完全な詳細については、AnyData::Format::Fooのドキュメントをご覧ください。FooにはadFormats()コマンドでリストされるフォーマットのいずれかが入ります。例えば 'CSV'、'XML'など。
特定のパーサーのさらに重要な詳細のいくつかだけを以下に示します。
固定長(Fixed)フォーマット
my $t = adTie( 'Fixed', $file, 'r', {pattern=>'A3 A7 A9'} );
固定長(Fixed)ファイルの先頭行にカラムの名前をいれたければ、固定長ではなくカラム区切りのフォーマットでなければなりません。これは先頭行でのカラム名の表示にそれ自身のフォーマットを使う他のフォーマットとは異なります。これはカラムの長さよりもカラム名の長さのほうが長いかもしれないために必要です。
<table>
<row row_id="1"><name>Joe</name><location>Seattle</location></row>
<row row_id="2"><name>Sue</name><location>Portland</location></row>
</table>
レコード・タグはデフォルトでは"row"という最初の子供になります。カラム名はレコードタグの属性とレコード・タグの下に入っているすべてのタグから生成されます。そのためこの例でのカラム命は"row_id"、"name","location"になります。
もしレコード・タグが最初の子供でなければ、指定する必要があります。例えば:
<db>
<table table_id="1">
<row row_id="1"><name>Joe</name><location>Seattle</location></row>
<row row_id="2"><name>Sue</name><location>Portland</location></row>
</table>
<table table_id="2">
<row row_id="1"><name>Bob</name><location>Boise</location></row>
<row row_id="2"><name>Bev</name><location>Billings</location></row>
</table>
</db>
この場合、それがツリーの最初の子供ではないので、"row"をレコード・タグとして指定する必要があります。カラム名はrowの親の属性、rowの属性、サブのタグからから作られます。つまり"table_id"、"row_id"、"name"、"location"になります。
XMLに出力するとき、出力を制御するためにDTDを指定することができます。例えば、CSVまたは配列(Array)からテーブルをインポートしたとき、XMLとして出力することができ、そのカラムがタグになり、どれが属性となるかを、タグのネストもDTDで指定することができます。
XMLフォーマット・パーサーは、それ自身はXML::Parserをベースとしている、Michel Rodriguez氏のXML::Twigの上に構築されています。これらのモジュールのパラメータは、adTie()や他のコマンドのためのフラグで渡すことができます。これにはXMLをどのように出力するかをしていするための"prettyPrint"フラグも含まれProtocolEncodingのように、ProtocolEncodingのデフォルトは'ISO-8859-1'、他のすべてのフラグはXML::TwigとXML::Parserのデフォルトが保たれています。詳細についてはそれらのモジュールのドキュメントをご覧ください。
注意:他のフォーマットとは違い、XMLフォーマットは変更をそれが入った時点では保存せず、adExport()コマンドで明示的に保存するよう要求したときにのみ変更は保存されます。
このフォーマットはMatt Sisk氏の素晴らしいHTML::TableExtractをベースとしています。 HTMLページから既にあるテーブルから読み込むために使うことができ、任意のデータソースから新しいHTMLテーブルを作ることができます HTMLテーブルにあるどのテーブルを使うのかは、column_names、depth、countフラグで制御することができます。 column_nameフラグが渡されると、行のセルとしてそれらの名前を持った最初のテーブルが選択されます。 depthとcountパラメータが渡されると、それはHTML::TableExtractドキュメントで指定されているようにテーブルを探します。 column_names、depth、countフラグが何も指定されなければ、そのファイルで最初に見つかったテーブルが選択され、その最初の行がそのテーブルのためのカラム名を決めるために使われます。 HTMLテーブル(HTMLtable)にエクスポートするとき、テーブル全体(table_flag)、カラム名が入った先頭行(top_row_flags)、そしてデータ行(data_row_flags)のプロパティを指定するフラグを渡すことができます。これらのフラグはCGI.pm tableコンストラクタの書き方に従います。例えば
print adExport( $table, 'HTMLtable', {
table_flags => {Border=>3,bgColor=>'blue'};
top_row_flags => {bgColor=>'red'};
data_row_flags => {valign='top'};
});
table_flagsは何も指定されなければ、デフォルトでは{Border=>1,bgColor=>'white'}になります。 top_row_flagsは何も指定されなければデフォルトでは{bgColor=>'#c0c0c0'} になります。 data_row_flagsは何も指定されなければ空になります。 言い換えれば、何もフラグが指定されなければ、テーブルは1のボーダーでカラム・ヘッダがグレー、データ行は白になります。 注意:このモジュールは選択されたテーブルを除いて、HTMLファイルについて*何も*保存しません。そのため選択したテーブル以上のことをファイルが持っていれば、adTie()を使ってテーブルを読み込み、adExport()で他のファイルにテーブルを出力したくなるでしょう。HTMLtableフォーマットを使っているときには、これがデータへの変更を保存するための唯一の方法です。adTie()コマンドはファイルへ*書き込みません*。
adTie()から返されるAnyDataハッシュはキーとして1つの値またはキーとして比較のハッシュへのリファレンスのどちらも使うことができます。もしハッスへのキーが1つの値であれば、ハッシュは1つの行に対して動作します。しかしハッシュへのキー事態がハッシュ・リファレンスであればハッシュは行のグループに対して動作します。
my $num_deleted = delete $table->{Sue};
この例はキー・カラムの値が'Sue'である1つの行を削除します。もし複数行がそのカラムに値'Sue'を持っていれば、先頭の行だけが削除されます。これは単純な文字列をキーとして使っており、そのため1つの行にのみ動作します。
my $num_deleted = delete $table->{ {name=>'Sue'} };
この例はカラム'name'が'Sue'であるすべての行を削除します。キーとしてハッシュ・リファレンスを使っているので、これは複数の行に動作します。
。もし複数行がそのカラムに値'Sue'を持っていれば、先頭の行だけが削除されます。それは単純な文字列をキーとして使っており、このためそれは1つの行にのみ動作します。
この例で使われているハッシュ・リファレンスは1つのカラムの比較ですが、ハッシュ・リファレンスには複数カラムの比較もいれることができます。以下の例ではcountry, gender, そして age カラムの値が指定されたものと同じであるすべての行を削除します:
my $num_deleted = delete $table->{{ country => 'us',
gender => 'm',
age => '25'
}}
単純な文字列に加えて、その値には正規表現や数値やアルファベットの比較も指定することができます。以下の例ではすべての北アメリカでの25未満の男性('male')を削除します:
my $num_deleted = delete $table->{{ country => qr/mx|us|ca/,
gender => 'm',
age => '< 25'
}}
もし数値あるいは文字の比較が使われるならば、値とは空白で分けられた比較演算子が入った文字列でなければなりません。例えば'> 4'や'lt b'。
ハッシュ・リファレンスの種類は複数行を削除するだけでなく、行を更新するために使うことができます。事実、テーブルを更新するためにはハッシュ・リファレンスキーを使わなければ*なりません*。更新は1つの文字列キーではできない唯一の操作です。
検索ハッシュ・リファレンスはSELECTステートメントでも使うことができます。その場合には、比較上条件にマッチする行の配列へのリファレンスを返します:
my $male_players = $table->{{gender=>'m'}};
for my $player( @$male_players ) { print $player->{name},"\n" }
これは大きなテーブルで使うときには注意が必要です。選択されたすべての行をメモリ上の配列にあつめるからです。再び、'each'が大きなテーブルのためのよりよい方法です。以下のでは例と同じことをやっていますが、一度にメモリへ1行以上引っ張り込むことがありません:
while( my $row= each %$table ) {
print $row->{name}, "\n" if $row->{gender}=>'m';
}
複数行のための検索条件はadRows()関数でも使うことができます:
my $num_of_women = adRows( $table, gender => 'w' );
これはメモリ上にテーブル全体をひっぱてきません。1度には1行を数えます。
adTie()やadConvert()の最初のファイル・パラメータが"http://"や"ftp://"で始まっていれば、ファイルはリモートのURLとして扱われ、ファイルを取り出すために影でLWPモジュールが呼び出されます。もしファイルが認証が必要な領域にあれば、それを$flagsパラメータで与えることができます。
例:
# リモート・ファイルを読み込み、tieされたハッシュでアクセスする
#
my $table = adTie( 'XML', 'http://www.foo.edu/bar.xml' );
# 同じことをusername/password をつけて
#
my $table = ( 'XML', 'ftp://www.foo.edu/pub/bar.xml', 'r'
{ user => 'me', pass => 'x7dy4'
);
# リモート・ファイルを読み込み、それをHTMLテーブルに変換し、出力
#
print adConvert( 'XML', 'ftp://www.foo.edu/pub/bar.xml', 'HTMLtable' );
文字列と配列は入力データのソースとしても出力データのターゲットとしても使うことができます。文字列は配列リファレンスの唯一の要素として渡されなければなりません(言い換えれば鍵括弧の内側)。配列はカラム名の配列へのリファレンスが最初の要素、その後ろは行の値の配列へのリファレンスである配列へのリファレンスでなければなりません。
例:
my $table = adTie( 'XML', ["<x><motto id='perl'>TIMTOWTDI</motto></x>"] ); これは与えられた文字列をXMLフォーマットとして使い、結果としてのテーブルへの tieされたハッシュを返します。
my $table = adTie( 'ARRAY', [['id','motto'],['perl','TIMTOWTDI']] ); これはカラム名"id"と"motto"を使い、行の値を与え、 結果のテーブルへのtieされたハッシュを返します。
任意のフォーマットの空のtieされたハッシュを作るために空の配列を使うことができます。例えば:
my $table = adTie('XML',[],'c');
空のtieされたハッシュを作ります;
文字列と配列の使い方のさらなる例はadConvert()とadExport()をご覧ください。
AnyDataはflockの制約のもとでファイル・ロックを提供します--他のプロセスがそのファイルに同じようにflockを使ってアクセスし、flockをサポートしているプラットホームでしか機能しません。詳細についてはflock()マニュアル・ページをご覧ください。
いかにオープン・モードで与えたものが実際に何をするかを示します:
r = 読み込みのみ (LOCK_SH) O_RDONLY u = 更新 (LOCK_EX) O_RDWR c = 作成 (LOCK_EX) O_CREAT | O_RDWR | O_EXCL o = 上書 (LOCK_EX) O_CREAT | O_RDWR | O_TRUNC
"my $table = adTie(...)"のように使うとき、ロックつきでファイルをオープンし、1)ハッシュ変数($table)がスコープから外れる 2)ハッシュが未定義になる(例えば "undef $table") または 3)ハッシュが他のtieに再割り当てされるまでロックをあけます。
もしadTieがtieされたハッシュ変数を作ることなしに呼ばれると、ファイルは閉じられ、ロックはadTieが呼び終わるとすぐに解放されます。
例えば: print adTie('XML','foo.xml')->{main_office}->{phone}.
これは共有ロックを取得し、ファイルをオープンし、要求された値の1つを取り出し、 ファイルをクローズし、ロックを解放します。
以下の2つの例は同じ事をしていますが、最初の例ではファイルを一度オープンし、すべての削除をおこない、すべて終わるまで占有ロックをつづけ、ファイルをクローズしています。2番目の例では、ファイルのオープン、クローズを3回しています。削除のたびに一度占有ロックをし、削除の間にその占有ロックを解放します:
1. my $t = adTie('Pipe','games.db','u');
delete $t->{"user$_"} for (0..3);
undef $t; # ファイルをクローズし、ロックを解放します
2. delete adTie('Pipe','games.db','u')->{"user$_"} for (0..3);
# ハッシュ・変数が作られ何のでundefは必要ありません
時間を節約し、ファイルの末尾を除いてどこでも書き込むことを防ぐため、deleteコマンドをしているときに削除や更新が行われません。ユーザが削除しているときに削除されたレコードの位置がハッシュに格納され、ファイルがディスクに保存されるときにだけ、データベース全体をパックすることにより物理的に削除されます。
更新はファイルの末尾に新しいレコードを挿入し、古いレコードに削除のマークをつけることにより行われます。イベントの通常のコースでは、このすべてがトランスペアレントで、これについてまったく心配する必要はありません。しかしあなたが更新または削除した後、ファイルを保存する前にサーバーがダウンしていしまったら、削除された行はデータベースに残り、更新については複数の行があるかもしれません--古い更新されていない行と新しく更新された行。このような種類のイベントを恐れるのであれば、原始的な上記のセクションで表したような原始的な削除と更新を使ってください。まだ削除と保存の間にクラッシュするほんの小さな可能性はありますが、この場合、衝撃はほとんど1つの行です。(削除の取り扱いについて提案してくれたMatthew Wicklineに感謝します)
さらなる例についてはモジュールに含まれるREADMEファイルとtest.plをご覧ください。
特定のフォーマットの詳細については、 AnyData/Format/*.pm PODをご覧ください。
さらなるサポートについては、 comp.lang.perl.modulesをお使いください。
(原文のまま)
Special thanks to Andy Duncan, Tom Lowery, Randal Schwartz, Michel Rodriguez, Jochen Wiedmann, Tim Bunce, Aligator Descartes, Mathew Persico, Chris Nandor, Malcom Cook and to many others on the DBI mailing lists and the clp* newsgroups.
(原文のまま)
Jeff Zucker <jeff@vpservices.com>
This module is copyright (c), 2000 by Jeff Zucker. It may be freely distributed under the same terms as Perl itself.
ご意見、ご質問はこちらの掲示板で受け付けています。
またメールは河馬屋(Nifty)にお願いします。