From: EGUCHI Osamu Date: 1997-09-24T11:46:36+09:00 Subject: [ruby-list:4564] Re: Object#freeze えぐち です。 > 前田です。 > > In message "[ruby-list:4537] Re: Object#freeze" > "EGUCHI Osamu" wrote: > > |> $: とかは readonly だから $: += "." はできないわけです. > |> でも $: << "." はできる. ここがひっかかるところかもしれない. > | > |$:.type ==> Array > |なので、ちょっと違うぞなのですが、 > > +=と<<の違いはArrayでも同じですよね? 「readonly な変数」と「forzen String」を混同していました。 _o_ id が同じまま値を変更するのを禁止するのは frozen String の方でした。 > |「Object の時から、 freeze を実装してしまいましょう」 > > これはfreezeの実装はサブクラスに依存して、template methodをObjectで > 用意するということでしょうか? > あるいは、ひょっとして、 > > class Foo > def change_state > end > destructive :change_state > end > > foo = Foo.new > foo.freeze > foo.change_state => 例外 > > のような仕組を用意するということでしょうか? `template method' がよくわからないんですが、後者と大変近いです。 frozen? == TRUE での method の評価が can't modify frozen #{self.type} を起こすか否かを整然と決めなくてはなりません。 これはメソッドが、「レシーバに左辺値を要求するか」の管理です。 (C++ の const member function に相当します) 左辺値を要求するかの検査は、 + メソッド hogohoge? (hogehoge_p) は左辺値を要求しない + メソッド hogohoge! (hogehoge_bang) は左辺値を要求する + 代入(=) や 代入系(+=, -=、[]= etc.)) は左辺値を要求する + 他のメソッドは左辺値を要求しない で出来そうなな気がしましたが、 Array#<<, Array#push など ! が付かなくてもレシーバの値を 変更するメソッドは珍しくないので、、 動的な検出方法も考えました bang-method は、 frozen? のテストの対象となる−>例外を起こし得る として、、 def の評価の時点で、 bang-method を呼び出している。 メソッドにメンバか self をパラメータで呼び出している メンバを書き換えている。 イテレータは、ブロック内で同様に検査 を調べる事で bang-method の検出 *原理的には* できそうです。 この方法は こ す と が大きな問題になりそうです。 えぐち