2006 年 4 月 27 日 19 時 43 分

読み取り・書き込み専用


このアーカイブは同期化されません。 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 の分オーバヘッドが生じる上に、
メソッドが存在しなくて呼び出せないのか、
メソッド内でエラーが起きたのかの区別が難しい。

さて、どうするか。



Copyright (c) 1994-2007 Project Loafer. All rights reserved.