UNIVERSALクラス
自分用メモ。
Perlでblessされて作成されるオブジェクトは、すべてUNIVERSALクラスを継承するらしい。という話を聞きつつ、これまで特に用は無かったで放っておいたのだが、最近ちょっと気になって調べてみた。
perldoc UNIVERSAL
UNIVERSALクラスでいくつかのメソッドが定義されていて、他のクラスはすべてこれを継承するので、すべてのクラスでUNIVERSALクラスのメソッドが使用出来る。
isaメソッドは、指定したクラスを継承しているかどうかを調べる。canメソッドは、指定したメソッドのコードリファレンスを返す。VERSIONはpackage内の$VERSION変数の内容を返し、このとき引数があると、クラスの$VERSIONと比較してクラス側$VERSIONが小さいときにdieする。まぁ、やってみよう。
package Test; use strict; use base qw/ CGI Storable Template /; $Test::VERSION = '1.0.0'; sub new { my $class = shift; bless { @_ }, $class; } sub method { my $self = shift; my $key = shift; my $value = shift; if( $value ){ $self->{$key} = $value; } return $self->{$key} || "no key"; } 1;
こんな感じのモジュールを用意してみた。newはコンストラクタで、ハッシュリファレンスをセットするのみ。methodは自分自身のハッシュリファレンスにアクセスする。特に意味はない。まぁ、CGIとStorableとTemplateを継承するオブジェクトなんて実際には無かろうが、まぁ実験なんでいいや。
次にテストプログラム。test.plとした。
#!/usr/bin/perl use strict; use lib '/Users/a_aql/Desktop'; use Test; my $test = Test->new( test1 => 'foo', test2 => 'bar' ); # 実行テスト print "test?t: ".$test->method('test2')."?n?n"; # UNIVERSALクラスのメソッドを試す print "isa(CGI)?t: ".$test->isa("CGI")."?n"; print "isa(DBI)?t: ".$test->isa("DBI")."?n"; print "can(method)?t: ".$test->can('method')."?n"; print "can(foo)?t: ".$test->can('foo')."?n?n"; print "VERSION?t: ".$test->VERSION."?n?n"; # canで得られたコードリファレンスを実行してみる print "CODE REF?t: ".$test->can('method')->($test,'test1')."?n"; exit;
最初はひとまずTestクラスを実行してみる。次にUNIVERSALクラスのメソッドを試し、最後にcanで得られるコードリファレンスの実行を行ってみた。
実行結果は次の通り。
pico1:~/Desktop a_aql$ perl test.pl test : bar isa(CGI) : 1 isa(DBI) : can(method) : CODE(0x185c938) can(foo) : VERSION : 1.0.0 CODE REF : foo
まぁ、予定通りの結果が得られている。
何に使うか…結構思いつくものもあるのだが、とりあえずそれは思案中なので置いておくことにするかな。とにかく、すべてのクラスで使えることが保証されている訳で、クラスのチェックの時に安心して使うことが出来そうだ。モジュールで$VERSIONをセットする理由を今回初めて知ったとかは内緒だ。