このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。
さて、今までは読み書き両用でみてきたが、
現実には、読み取り専用のプロパティや、
書き込み専用のプロパティもある。
property のインタフェースは、
プロパティ名、getter、setter の名前を渡すことだが、
読み取り専用や書き込み専用の場合どうするか。
1. getter、setter として、undef を渡せるようにする。
getter が undef の場合、読み取りはできない、
setter が undef の場合、書き込みはできない。
そのように実装することは可能だ。
property 側は undef かメソッド名か調べ、
undef であれば、croak すればいいというわけだ。
例えば、読み取り専用のプロパティを定義した場合、
'set' には、undef が渡される。
実行時にプロパティに対して値を代入した場合、
undef かどうか調べて、呼び出しができないことを通知する。
sub STORE {
my ($this, $value) = @_;
my $method = $this->{'set'};
if (not defined $method) {
croak "Can't set value to this property.";
}
$this->{'object'}->$method($value);
}
この方法はシンプルではあるが、継承が絡むと面倒になる。
あるクラスが property モジュールを使って、
読み取り専用プロパティを実装し、
それを継承したクラスで代入を可能として拡張した場合、
プロパティもオーバライドする必要がある。
それを忘れると set_XXXX でしか呼び出せなくなってしまう。
2. 実行時に呼び出し可能か調べる。
モジュールは、利用する側がどう扱うか分からないので、
継承の問題などを考えると、この方法がよさそうだ。
しかし、実行時に動的にメソッドを呼ぶことはできたが、
メソッドが存在するかどうかを調べる方法はあるのだろうか。
eval を使ってエラーを捉えればできそうだが、
eval の分オーバヘッドが生じる上に、
メソッドが存在しなくて呼び出せないのか、
メソッド内でエラーが起きたのかの区別が難しい。
さて、どうするか。