From: matz@... (Yukihiro Matsumoto) Date: 1997-08-13T15:44:02+09:00 Subject: [ruby-dev:122] Re: meta programming features まつもと ゆきひろです In message "[ruby-dev:121] Re: meta programming features" on 97/08/13, 石塚圭樹 writes: |けいじゅ@日本ラショナルです. |foo = Foo.new |foo.eval "X = 1" | |は何を行うことになるのでしょう? | |1. 常に, Foo#Xを定義する. |2. 常に, fooの特異クラスのXを定義する. |3. Foo#Xがなければ Foo#Xの定義, 存在すればfooの特異クラスのXを定義する. |4. 今のところ未定義 |5. その他 4です.どうするのが良いと思いますか? 現行eval(private)では1ですね. 現行evalの基本は「そこにコードがそのままあった場合と同じ動き をする」ことです.しかし,そもそもメソッド定義と定数定義には 存在できない場所がありますから,そういう場所でもevalの挙動は 任意に決められるわけです. で,現状ではそのメソッドを定義している(定義を囲んでいる)クラ スをメソッド,定数の定義先としているわけです. で,考えられる変更点は * evalをpublicにする この場合,「コードがそこに」というのは成立しなくなります が,これは「コードがそのクラスのメソッドに」ということで まあ,受け入れられると思います. * evalでのメソッドとクラスの定義先をクラスから特異クラスに 変更する. 互換性は無いですが,受け入れられないことは無い変更です. ただし,関数形式でevalが呼ばれた時には現在の動作の方が自 然に見える気はします. 逆にメソッド形式で呼ばれた時には特異クラスに定義した方が 自然なんですよねえ.とはいえ,メソッドが関数形式で呼ばれ たかどうか知る方法は無いですし. なんですよねえ. |トップレベルにおいて, evalで関数定義を行うと: | | eval "def foo; ...; end" | |メインオブジェクトの特異メソッド定義になっちゃうわけですよね? それはいくらなんでも使いにくいんで,Object#evalの挙動を変更 するなら,main.evalを再定義して,トップレベルではObjectクラ スに対してメソッドや定数を定義するようにするでしょう,多分. |で, どうしたらいいかというと: | |1. このまま. |2. メソッド定義は定数定義と合わせる. |3. 特異メソッドfooが定義されていれば, 特異メソッドの定義. 定義されてい | なければFoo#fooの定義. 特異メソッドを明示的に定義したい時には, def | obj.foo を用いる. |4. | |などなどがあると思います. なんか3は動きが複雑だなあ.定数メソッドともクラスにするか特 異クラスにするかどちらかで統一した方が良さそうに思います. |Object#typeは, 特異クラスを返した方がいいのか, あくまでもクラスを返し |た方がいいのか... なんとなく特異クラスを返そうという気になっています. まつもと ゆきひろ /:|)