October 11, 2003

Perl OOP におけるクラスの実装方法

[ Perl ]

Perl で OOP するにあたってはコンストラクタの書き方やアクセサの書き方に色んな方法があります。素で書くと

package Dog;
 
use strict;
use warnings;
 
# コンストラクタ
sub new {
    my $class = shift;
    my $self = {};
    bless $self, $class;
 
    return $self;
}
 
# アクセサ
sub name {
    my $self = shift;
 
    @_ ? $self->{name} = shift : $this->{name};
}
 
1;

あたりが定番だと思います。インスタンスフィールドをハッシュで実装して、アクセサは getter と setter を兼ねるメソッドとして定義。コンストラクタにおける初期化処理を $self->init(@_); とかして分離するとか、インスタンスフィールドをリストで実装するとか、プライベートなフィールドは命名規則で $self->{_age} とかするとか色んなやり方、流儀があります。

僕は最近、コンストラクタやアクセサを書くのが面倒なので、CPAN モジュールを使って書いてます。

package Dog;
 
use strict;
use warnings;
use base qw (Class::Accessor Class::Fields);
use fields qw( _age name );
__PACKAGE__->mk_accessors(__PACKAGE__->show_fields('Public'));

と言った具合です。Class::Fields を継承して Class::Accessor を Mix-in します。fields プラグマを利用してインスタンスフィールドを宣言するのですが、Class::Fields を継承しておくと、_ で始まる名前のフィールドはプライベートフィールドとして扱われます。

Class::Accessor->mk_accessors にフィールド名を渡すとアクセサを作ってくれるのですが、そこに Class::Fields->show_fields('Public') を渡すことによって public なフィールドのみアクセサを作ることができます。ついでにコンストラクタも作ってくれます。この場合 name のみアクセサが作られて、_age のアクセサは無く外部からは見えません。

コンストラクタやアクセサで変わったことがやりたければオーバーライドしてしまえば良いです。

他にも CPAN には Class::MethodMaker とか Class::MakerClass::MakeMethodsだとか、Class::Declare だのなんだか他にも色々あって把握しきれません。どれがデファクトなんだろう。

Posted by naoya at October 11, 2003 02:27 AM | トラックバック (0)  b_entry.gif
トラックバック [0件]
TrackBack URL: http://mt.bloghackers.net/mt/suck-tbspams.cgi/509
コメント [3件]

ちょうどPerlネタでClassを使いたかったので、参考になりました。
フィールド名の _age の由来がよくわかりませんが、
age と _sage のほうがわかりやすかったかも知れませんw

[1] Posted by: ooba at October 11, 2003 02:58 AM [返信]

いやエイジですよ、エイジ!

ネタにマジレスか?(笑)

[2] Posted by: naoya at October 11, 2003 03:03 AM [返信]

寝る直前にふと気付いて自己フォローしにきたら、時すでに遅し(恥)

[3] Posted by: ooba at October 11, 2003 04:07 AM [返信]