まつもと ゆきひろです

In message "[ruby-list:3415] Re: meta programming features"
    on 97/07/23, 石塚圭樹 <keiju / bc.mbn.or.jp> writes:

|けいじゅ@今はフリー(^^;;;です. 

|>例示された中では ingredients くらいならなんか伝わる気がしま
|>すけど.
|
|やっぱ, flavors ですかねえ...

ですかねえ.もうちょっとかんがえましょう.

|>これでも外側のスコープでaがローカル変数として代入されている
|>場合とそうでない場合で挙動が違ってしまいます.
|
|そうなんだ, 
|
|  a = "Foo"
|  proc{|a| a = "Bar"}.call
|  print a
|=======================
|  Foo
|
|となるという意味? 

ちゃいます.この場合 a は(イテレータブロックの外で代入されて
いるので)常に静的ローカル変数です.ですから,この結果は

=======================
  Bar

です.動的ローカル変数とは「イテレータブロックの中で最初に代
入された変数」のことです.

|>|a = "Foo"
|>|eval "|a| A = a", Foo.class_binding, a
|>
|>evalじゃない別のものになってしまいますけど,これはこれで意味
|>があるのかなあ.
|
|別のものですか... 

evalに渡す文字列はrubyプログラムですが,"|a| A = a"は完全な
rubyプログラムではありませんから.たとえば,

  ruby -ce "|a| A = a"

してみれば分かると思いますが.

|うーん. なるほど... ところで, バインディングってどんなオブジェクトなん
|です? 

構造はProcと同じです.ちなみにProcをbindingとして渡しても動
作します.Procはイテレータがスタック上に持っている情報をオブ
ジェクト化したもので,だいたい以下のようなものを持っています.

  * 静的ローカル変数フレーム
  * 動的ローカル変数フレーム
  * self
  * 現在のclass(定数・メソッドの定義先)
  * そのほか付加的な値

|そうすると, 考えられるAPIとしては:
|
|  Module#モジュール定義

   Module#newが使えるようになります.

|  Module#クラス定義

   Class#newが使えるようになります.

|  Module#定数定義

   Module#set_constant(name, value)にしましょう.

|  Module#メソッド定義

   名前はModule#define_methodで良いと思うのですが,どういう
   APIにしましょうか?

     Foo.define_method("foo") do |arg|
        ..
     end

   なんてのも変な気がしますが

     Foo.define_method("foo", "arg", "...")

   よりはましな気がします("..."はメソッドの定義部).

|  Module#alias

   Module#alias_method(new, old)にしましょう.

|  Module#undef

   Module#undef_method(name)にしましょう.

|ぐらいですか. あと, Module/Class 関係のメソッドでprivateなメソッドがあ
|りますが, それをpublicにする必要がありますね. 

public,private,module_functionなどですか? うーん,そうした
方が良いのでしょうか.せっかくprivateになっているのになあ,
という気もしますが.…仕方ないか.

                                まつもと ゆきひろ /:|)