 | レベル: 中級 Teodor Zlatanov (tzz@bu.edu), Programmer, Gold Software Systems
2000年 7月 01日 データの保管は、コンピューター・プログラミングに共通の問題です。CPAN のPersistent クラスを使用すると、データの作成、検索、および管理を単純化する共通インターフェースにより、データ保管が簡単に行えるようになります。Persistent クラスは、オブジェクト指向性を介して、ユーザー独自のデータ・クラスの上位クラスとして、ユーザーのプロジェクト内でその存在を意識することなく使用することができます。
永続化の概要
すべてのプログラマーは、データ永続性の問題を解決する必要があります。たとえば、ファイルへの文書の保管およびデータベースへのトランザクションの保管は、どんなに単純なアプリケーションの場合でも、かなりの手間を必要とする作業です。データ永続性は、データの保管と検索をどのように行うかを指定する、プログラムとストレージ・デバイスの間で取り決められた、ある種の約束として定義することができます。
CPAN の定義: 「CPAN は Comprehensive Perl Archive Network のことです。Comprehensive (包括的な): 目的は、ユーザーのために必要なすべての Perl 素材を収納することにあります。Archive (アーカイブ): 1999 年 9 月現在で 760 メガバイト。Network (ネットワーク): CPAN は世界中の 100 個所を超えるサイトでミラーリングされています。」
この記事では、作者と読者の両方がオブジェクトの属性を前もって知っている場合に、オブジェクト属性を永続化する方法を中心に説明します。オブジェクト属性の動的な検出、あるいはオブジェクト属性以外のもの (たとえば、振る舞い) の保管に関するトピックは、扱いません。そのようなトピックについて十分に説明するためには、かなり多くの段落を必要とするからです。
オブジェクト指向プログラミング、データベース、Perl、および Perl 継承に関する知識があると、この記事が理解しやすくなります。
オブジェクト属性の永続化は、ソフトウェア開発プロセスの一部にすぎません。まず、永続化の要件を決定しなければなりません。何を保管する必要があるのか? 何を復元する必要があるのか? 保管したデータを復元する前に、手作業でデータを編集する必要があるのか? このような質問事項により、ソフトウェアがデータ永続化を実現する方法が決まります。残念なことに、あるプロジェクトの正確な永続化要件を単一の質問表だけで決めることはできません。ソフトウェア設計者は的確な設計を行って、プロジェクトの要件を定義し、その要件を満たさなければなりません。その結果としてのソリューションは、単なるもっともらしい業界用語としてのソリューションではなく、問題に対する解決策となっていることが大切です。たとえば、レンガだけで家を建てることができないように、XML によってデータ永続化の問題を解決することはできません。
永続データの例
Perl ファイル simple は、事前定義されたキーワードのセットの永続化がどれほど簡単にインプリメントできるのかを示しています。この方法には多くの問題があります。つまり、ファイル・フォーマットが勝手に決められること、キーワードのセットが 1 つしか保管されないこと、オブジェクトが視野に入っていないこと、データ値が 1 行のテキストに制限されていることなどです。
Persistent クラスの単純な使用法: Persistent::File
Persistent クラスは、データ永続化を簡単に行えるようにすることを目的としています。その目的を達成するために、ユーザーはドキュメンテーションを読む必要があります。これは、ユーザーに代わってデータ永続化を処理する 作成済みの便利なクラスを入手するための対価としては、ささいなものです。ですから、この作業に数分または数時間を割くことにより、後で費やす時間を短くすることができます。ドキュメンテーションおよび例については、Persistent クラスのホーム・ページ (参考文献を参照) を見てください。
私たちの最初の例 first
は、Persistent::File モジュールのドキュメンテーションで示された簡単な例に基づいて作られ、永続化を達成するためのステップを明確にします。
リスト 1: データの定義
my %problems = (
'Homework 1, Problem 1' => [0,5,2],
'Homework 1, Problem 2' => [1,8,5],
'Homework 1, Problem 3' => [2,2,4],
'Homework 1, Problem 4' => [3,0,3],
'Homework 1, Problem 5' => [4,1,2],
);
|
最初に、データ・ストアに保管するデータを定義します。Persistent クラスでは、データ・ストアはファイルやデータベースなどの抽象ストレージ・デバイスです。この例は自己完結型ですが、データはどのようなソースからでも得ることができます。
リスト 2: エラーをトラップするための eval の使用
use English;
eval
{
};
print "An error occurred: $EVAL_ERROR\n" if $EVAL_ERROR;
|
実行中にエラーが発生した場合にプログラムが死んでしまうのは困りものですから、私たちが行うことをすべて eval ステートメントにラップします。English モジュールを使用すると、エラー・メッセージとして $@ の代わりに $EVAL_ERROR が使用されるようになります。
リスト 3: データ・ストアの定義
# create a persistent object from a file
my $equation = new Persistent::File('variables.txt'); |
次に、新しい Persistent::File オブジェクトを作成します。このオブジェクトの内容は variables.txt ファイルに保管されます。
リスト 4: 属性の定義
$equation->add_attribute('name', 'ID', 'VarChar', undef, 80);
$equation->add_attribute('x', 'Persistent', 'Number', 0, 10);
$equation->add_attribute('y', 'Persistent', 'Number', 0, 10);
$equation->add_attribute('z', 'Persistent', 'Number', 0, 10);
$equation->add_attribute('answer', 'Transient', 'Number', undef, 10); |
ユニーク ID、3 つの永続データ・メンバー、および 1 つの非永続 (一時) データ・メンバーの、5 つの属性を作成します。Persistent クラスは、データ・メンバーにアクセスするために必要な機能 (たとえば、$equation->answer()) を自動的に作成します。
リスト 5: データ・ストアの消去
$equation->restore_all();
$equation->delete while $equation->restore_next(); |
restore_all メソッドは、データ・ストア全体の内容を検索します。restore_where メソッドは、なんらかの基準に一致する "複数" のオブジェクトを選択するために使用でき、restore メソッドは、同じく "単一" のオブジェクトを選択するために使用することができます。delete メソッドは現行 (カレント) の式を除去し、restore_next メソッドは次に復元されるオブジェクトに移動します。
リスト 6: オブジェクト・データの保管
# now store the problems in the datastore
foreach my $key (keys %problems)
{
$equation->clear;
$equation->name($key);
$equation->x($problems{$key}->[0]);
$equation->y($problems{$key}->[1]);
$equation->z($problems{$key}->[2]);
$equation->save;
} |
古い属性を消去し、新しい属性を設定したうえで、そのオブジェクトをデータ・ストアに保管します。データ・ストアの内容を消去したばかりなので、名前キーが競合することはないことは分かっていますが、通常は、save メソッドで既存のキーを上書きしようとして例外を引き起こすことがないように、この検査を行います。
リスト 7: homework 1 式の検索
# query the datastore for equations from homework 1
$equation->restore_where(qq{name =~ 'Homework 1'});
while ($equation->restore_next())
{
# do something with each equation
} |
最後にデータ・ストアをひと通り調べて、名前キーに「Homework 1」というストリングが含まれているオブジェクトを探し、それらの各オブジェクトで操作を実行します。
この例それ自体は、あまり興味を誘うようなものではありませんが、次の点を留意する必要があります。
- 永続オブジェクトに任意の数の属性を追加できるようになっている。
- 保管された任意のオブジェクトを選択的に検索できる。
- そのオブジェクトの属性を認識している他の任意のプログラムはすべて、同じデータ・ストアを使用できる (詳しくは、「Persistent クラスからの継承」の項を参照してください)。
作成済みのモジュールを使用することにより、難しい問題を楽に解決することができました。すごいですね!
Persistent::DBI の使い方
Persistent::DBI クラスと Persistent::Base クラスの違いに関する最新の解説については、Persistent::DBI のドキュメンテーションを参照してください。基本的に、Persistent::DBI はデータベースへの接続を可能にし、その接続が確立された後は他の Persistent::Base クラスとまったく同じように振る舞います。リスト 3 で示した行を、次の行で置き換えることができます。
リスト 8: データベース化するデータ・ストアの定義
my $database = 'test_database';
my $host = 'db_host';
my $user = 'dali';
my $password = 'MeltingClocks';
my $table = 'persistence_test_table';
my $equation = new Persistent::MySQL(
"DBI:mysql:database=$database;host=$hostname",
$user, $password, $table);
|
Persistent::MySQL が Persistent::DBI のサブクラスであることに注意してください。Persistent::DBI だけを使用したのでは機能しません。データベースに対応する特定のモジュールを使用する必要があります。ありがたいことに、データベースを切り替えても、コードを変更する必要はありません。(use ステートメントや new ステートメントなどの、名前で Persistent::MySQL を記述しているところを除く)。継承を使用してデータベース選択からプログラムを分離する方法については、「Persistent クラスからの継承」の項を参照してください。
リスト 9: 別の照会構文
# query the datastore for equations from homework 1
$equation->restore_where(qq{name LIKE '%Homework 1%'});
|
SQL SELECT ステートメントを使用するようになったので、restore_where 引数は Perl パターン・マッチングから SQL WHERE 文節の構文に変更されます。
表は前もって作成しておかなければなりません。Persistent::MySQL が表を作成してくれるわけではありません。表を作成するためのプログラムを別に書くか、あるいは必要な機能を継承によってユーザーのクラスに追加してください。
この表は、ユーザーの属性の定義と一致していなければなりません。たとえば、式の表の 1 次データベース・キーは、Persistent クラスでも 1 次キーでなければなりません。(これは、インプメント作業の前にきちんとした設計が必要であることを示す一例です。)
リスト 8 とリスト 9 は、 first second
には、それらの変更内容が含まれています。
Persistent クラスからの継承
ファイル Equation.pm
には、Persistent::DBI クラスからの継承に必要なすべてのコードが含まれています。簡単でしょう? 基本的に、add_attribute の呼び出しはローカルの初期化メソッドで行われます。ここでは、それ以上のことができます。たとえば、データベース内に表が存在しない場合には、表を作成することができます。しかも、基本的な方法は非常に単純です。
セキュリティーに関する注:
通常、表の作成は、データベース内の特権ユーザーだけが行えるようになっています。このため、セキュリティー・ポリシーとの関係で機能しないようなプログラムの作成に無駄な時間を費やさずに済むように、表の作成についてデータベース管理者と話し合っておくことをお勧めします。
リスト 10: Equation.pm モジュール、Persistent::MySQL の拡張
#! /usr/bin/perl -w
package Equation;
@ISA = qw(Persistent::MySQL);
use strict;
use Persistent::MySQL;
sub initialize
{
my $self = shift;
$self->SUPER::initialize(@_);
# define attributes of the object (the contract)
# this is the primary object identifier key, a 10-character name
$self->add_attribute('name', 'ID', 'VarChar', undef, 80);
# x, y, and z are persistent numbers with default values of 0 and length of 10
$self->add_attribute('x', 'Persistent', 'Number', 0, 10);
$self->add_attribute('y', 'Persistent', 'Number', 0, 10);
$self->add_attribute('z', 'Persistent', 'Number', 0, 10);
# this attribute will NOT be saved
$self->add_attribute('answer', 'Transient', 'Number', undef, 10);
}
1;
|
@ISA の行に注意してください。この行は Perl に対し、Equation クラスが Persistent::SQL から派生することを知らせています。
ファイル third second
から add_attribute の行 (つまり、"use Persistent::MySQL") を除去し、リスト 11 を追加したものです。
リスト 11: 新しい use ステートメント
use lib '.';
use Equation;
|
これは、Perl に対して、Equation モジュール equation
を使用すること、および現行ディレクトリー内で Equation.pm を探すことを指示しています。
ここで示した方法は、より複雑な問題に対応させるために簡単に拡張することができます。手始めとしては、参考文献に示した情報で十分なはずです。
まとめ
CPAN Persistent クラスは、データ永続化のソリューションを求めるユーザーのにとって、強力な味方となります。経験を積むにつれて、Persistent クラスの最上の用途は継承であることが分かると思います。データ永続化を上手に行うためには、Persistent クラスだけでなく、きちんとした設計と属性の明確な定義が必要である、ということを忘れないでください。
参考文献
- Dave Winters のPersistent クラス・ホーム・ページ には、このページで述べた Persistent クラスに関する追加情報が記載されています。この情報は CPAN サーチ・ページでも探すことができます。
-
CPAN (Comprehensive Perl Archive Network) には、ユーザーにとって必要なすべての Perl モジュールが含まれています。
- Perl 全般に関してはperl.com を参照してください。
- Programming Perl, 2nd Edition (Larry Wall, Tom Christiansen, および Randal L. Schwartz 著 (O'Reilly, 1996)) は、Perl に関する現在最高のガイドですが、5.005 と 5.6.0 が発表された今では、やや内容が古くなっています。
- Object Oriented Perl (Damian Conway 著 (Manning Publications, 2000)) は、モジュールおよびオブジェクト指向性に関するすばらしい手引きです。
- 「perltoot」および DBI perldoc ページを参照してください。
著者について  | 
|  | Teodor Zlatanov 氏は、1999 年にボストン大学を卒業し、コンピューター・エンジニアリングの分野で理学修士号を取得しました。1992 年以来、Perl、Java、C、および C++ を使用して、プログラマーとして働いています。興味の対象は、オープン・ソースのテキスト分析処理、3 層クライアント・サーバー・データベース・アーキテクチャー、UNIX システム管理、CORBA、およびプロジェクト管理です。メール・アドレスは
tzz@bu.edu です。 |
記事の評価
|  |