2008-03-01から1ヶ月間の記事一覧

14.5 大規模なDBMファイルをソートする

DB_FileのBツリーバインドを機能を使用して、自分で独自に作成した比較関数を指定する。 use DB_File; # エクスポートされた$DB_BTREEハッシュリファレンスを使用して # キーの比較を行うPerlのサブルーチンを指定する $DB_BTREE->{'compare'} = sub { my ($…

14.4 DBMファイルをマージする

それぞれのハッシュをリストとして処理する %OUTPUT = (%INPUT1, %INPUT2); それぞれのキーと値のペアをループ処理する %OUTPUT = (); foreach $href (\%INPUT1, \%INPUT2) { while (my($key, $value) = each(%$href) { if (exists $OUTPUT{$key}) { # どち…

14.3 異なるDBMファイルに変換する

DBMファイルからキーと値を読み取り、それらを異なるDBMフォーマットの新しいファイルに書き込む #!/usr/bin/perl -w # db2gdbm: DBをGDBMに変換する use strict; use DB_File; use GDBM_File; unless (@ARGV == 2) { die "Usage: db2gdbm infile outfile\n"…

14.2 DBMファイルを空にする

tieを使用してデータベースを開き、そのデータベースに関連づけられたハッシュに()を設定する。 use DB_File; tie(%HASH, "DB_File", $FILENAME) or die; %HASH = (); untie %HASH; ファイルを削除してから、改めて開き直す。 unlink $FILENAME or die; tie(…

14.1 DBMファイルを作成/使用する

DBMデータベースを作成し、値を格納、入力、参照、削除したい。 tieを使用してデータベースを開き、ハッシュによってアクセスできるようにする。必要な操作が完了したら、untieを呼び出す。 use DB_File; # データベースモジュールをロードする。 tie %HASH,…

13.15 tieでマジック変数を作成する

tieによって関連づけられた変数の解釈方法 ユーザコード 実行されるコード tie $s, "SomeClass" SomeClass->TIESCALAR() $p = $s $p = $obj->FETCH() $s = 10 $obj->STORE(10)

13.14 演算子のオーバーロード

自分が作成したクラスを継承しているオブジェクトにおいて、==や+などの使い慣れた演算子を使用したい。 overloadプラグマを使用する use overload '<=>' => \&threeway_compare; sub threeway_compare { my ($s1, $s2) = @_; return uc($s1->{NAME}) cmp uc…

13.13 オブジェクトで環状データ構造に対処する

自己参照データ構造でしか表すことのできないデータがある。従って、たとえそのデータ構造が不要になっても、Perlに組み込まれている参照ベースのガベージコレクションでは、そのことを認識することができない。 自己参照データ構造へのポインタを保存する非…

13.12 AUTOLOADで属性メソッドを生成する

自分で作成するオブジェクトにおいて、複数のデータフィールドを設定したり、取得したりするためのアクセッサメソッドが必要である。ただし、それら全てを一度に一つずつ書く手間を簡略化したい。 PerlのAUTOLOADメカニズムを一種のプロキシメソッド生成手段…

13.11 オーバーライドされたメソッドにアクセスする

自分で作成したクラスのコンストラクタメソッドによって、親クラスのコンストラクタをオーバーライドしている。この状況で自分のコンストラクタから親クラスのコンストラクタを呼び出す必要がある。 疑似クラスSUPERを使用する。 sub meth { my $self = shif…

13.10 継承可能なクラスを書く

自分で設計したクラスが他のクラスやオブジェクトによる継承に耐えられるくらい十分に堅牢であるかを確認したい。 自分のクラスに対して、"空のサブクラステスト"を適用する。 Personと言う名前のクラスを実装したと仮定する。 package Person; sub new { my…

13.9 サブクラスのインスタンスを判定する

あるオブジェクトが特定のクラスまたはそのサブクラスのインスタンスであるかどうかを判定する。 UNIVERSALと言う特別なクラスに含まれているメソッドを次のような方法で使用する。 $obj->isa("HTTP::Message"); # オブジェクトメソッドとして HTTP::Respons…

13.8 メソッドを間接的に呼び出す

実行時にならないと判明しない名前を使用して、メソッドを呼び出す。 メソッド名を文字列として、スカラ変数に保存し、実際のメソッド名を矢印演算子の右側に使用するときに、その変数を使用する。 $methname = "flicker"; $obj->$methname(10); # $obj->fli…

13.6 クローンを作成するコンストラクタ

既存のオブジェクト上で呼び出されるコンストラクタメソッドを作成する必要がある。ただし、このコンストラクタメソッドが呼び出された場合には、新しいオブジェクトを初期化するためのデフォルト値として、元のオブジェクトの値を使用しなければならない。 …

13.7 コピーコンストラクタ

自分が作成したクラスのユーザにコピーメソッドを提供したい。または、クラスによってコピーメソッドが提供されていないオブジェクトをコピーしたい。 標準モジュールのStorableに含まれているdclone()関数を使用する。 use Storable qw(dclone); use Carp; …

13.5 構造体としてのクラスの使用方法

標準モジュールのClass::Structのstructを使用して、Cプログラミング言語の構造体に類似したデータ構造を宣言する。 use Class::Struct; # 構造体専用のモジュールをロードする struct Person => { # "Person"の定義を行う name => '$', # nameフィールドは…

13.4 クラスデータを管理する

1個のオブジェクトだけでなく、クラス全体においてメソッドが呼び出されるようにする必要がある。 クラスの名前を含む文字列を指定して、クラスメソッドを呼び出す。 package Person; $Body_Count = 0; sub population { return $Body_Count } sub new { $Bo…

13.3 インスタンスデータを管理する

オブジェクトハッシュの適切なキーにアクセスして、その値を取得および設定するメソッドを作成する。 sub get_name { my $self = shift; return $sef->{NAME}; } sub set_name { my $self = shift; $self->{NAME} = shift; } 引数を渡されたかどうかに応じて…

13.2 オブジェクトを破棄する

オブジェクトが不要になったら、その度に特別なコードを実行する。 DESTROYと言うメソッドを使う。オブジェクトの参照が切れたとき、プログラムが終了するときに呼び出される。 sub DESTROY { my $self = shift; printf("$self dying at %s\n", scalar local…

13.1 オブジェクトを作成する

単純なコンストラクタ sub new { my $class = shift; my $self = {}; bless($self, $class); return $self; } 初期化とメモリ割当/blessを分離する方法 sub new { my $class = shift; # 作成するオブジェクトのクラス名を取得する my $self = {}; # 新しいメ…

12.23 プログラム: インストール済みのモジュールのバージョンと説明を検索する

CPANPLUSモジュールを使用する方法 use CPANPLUS::Backend; use Data::Dumper; $cp = CPANPLUS::Backend->new; $installed = $cp->installed->rv; # インストール済みのモジュールの一覧を取得する。 foreach my $module (sort keys %$installed) { # モジュ…

12.22 例: モジュールのテンプレート

package Some::Module; # Some/Module.pmに保存する use strict; require Exporter; # バージョンチェック用にバージョンを設定する。 our $VERSION = 0.01; our @ISA = qw(Exporter); our @EXPORT = qw(&func1 &func2 &func4); our %EXPORT_TAGS = (); # 例…

12.20 PODでドキュメントを作成する

12.21 CPANモジュールのビルドとインストール

モジュールをダウンロードしてインストール % gunzip Some-Module-4.54.tar.gz % tar xf Some-Module-4.54.tar % cd Some-Module-4.54 % perl Makefile.PL PREFIX= % make % make test % make install モジュールを直接インストール % perl -MCPAN -e "insta…

12.19 Inline::CでCの拡張モジュールを書く

Perlから呼び出すことができる関数をCで書きたい。 CPANで入手できるInline::Cモジュールを使用する use Inline::C; $answer = somefunc(20, 4); print "$answer\n"; __END__ __C__ double somefunc(int a, int b) { /* Inlineは基本的なCの型の大半を認識す…

12.17 h2phでCの#includeファイルを変換する

% cd /usr/include; h2ph *.h */*.h

12.18 h2xsでCコードを含むモジュールを作成する

使用しているシステムに固有のC関数にPerlからアクセスしたい。 h2xsツールを使用する % perl Makefile.PL % make

12.15 警告をカスタマイズする

自分のモジュールにおいてレキシカルな警告に関する呼び出し側の設定を重視してそれに対応する処理を行いたいが、それらの設定を確認しようと思っても、前もって定義されている$^W変数の値を検査することができない。 use warnings::register;

12.16 パッケージを間接的に参照する

実行時にならないと名前のわからないパッケージに含まれている変数や関数を参照する必要がある。ただし、$packname::$varnameのような構文は不正である。 シンボリックリファレンスを使用する。 { no strict "refs"; $val = ${ $packname . "::" . $varname …

12.13 全てのパッケージの組み込み関数をオーバーライドする

現在のパッケージだけでなく、自分のプログラム全体に含まれている主要な組み込み関数の定義を変更する必要がある。 シンボルテーブルを直接操作することによって、CORE::GLOBALと言う疑似パッケージに関数を手動でインポートする。 *CORE::GLOBAL::int = \&…