深く考えすぎない方がいいのだと思いました。
use fields と Class::Accessor でプライベートフィールドをアクセサ経由でだけ外部に公開しようと思ったのですが、駄目でした。
Class::Accessor の perldoc によれば、以下のような利用法がお勧めみたいですが。
package Altoids; use base qw(Class::Accessor Class::Fields); use fields qw(curiously strong mints); Altoids->mk_accessors( Altoids->show_fields('Public') ); sub new { my $proto = shift; my $class = ref $proto || $proto; return fields::new($class); }
気になる問題は2つあります。
- publicなフィールドのpublicなアクセサなので、アクセサ通さなくてもいいっポク見える
- Class::Accessor::new が使えない・・・
最初の問題を解決するには、accessor_name_for とか mutator_name_for をオーバーライドして、先頭の"_"を外した物をアクセサの名前にするといいかもしれないですね。まだ試してませんけど。
もう一つの問題はどういうことかと言うと、Class::Accessor::newを使うと、こういうことができるのです。
my $altoids = new Altoids({curiously => 50, strong => 10, mints => 200});
fields::newではこれは無理。ほんとは両方呼んでどうにかできればいいのですが、どちらも真面目なコンストラクタとなっており、あれこれいじりましたが結局両方呼ぶことができませんでした。
ところで、use fields を無理して使おうとしてるわけですが、こいつも実はそんなに完璧なものではありません。その辺は次のエントリにて。
ちなみに、Class::Std を使うとこの辺は上手く行きそうなんですが、どうもインスタンスのデータの実体がそのインスタンスの保持するポインタと遠い部分にあるってのは気持ちが悪いです。