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::Maker、Class::MakeMethodsだとか、Class::Declare だのなんだか他にも色々あって把握しきれません。どれがデファクトなんだろう。