From: keiju@... (ÀÐÄͷ½¼ù ) Date: 1997-03-21T00:59:45+09:00 Subject: [ruby-list:2397] Re: eval()'s context けいじゅ@SHLジャパンです. In [ruby-list :02395 ] the message: "[ruby-list:2395] Re: eval()'s context ", on Mar/20 03:07(+0200) Shin-ichiro Hara writes: >そういえば binding を使ったことがなかった。(^^; >どうやって使うんでしょう。 >例をあげていただくとありがたいのですが。 実用的な例としては, debug.rb が使っているらしいです. >> eval()を用いたメソッド定義って2段階にトリッキーなのであまり使っている >> 人はいないでしょうね. >> >> 1段目: クラス文(class ...)によるクラス定義は複数できる. > >これは eval を使わなくてもそうですよね。例えば、 (中略) >みたいに続けて定義できるということですよね。 >そういう事じゃないのかな。 そうです. 原さんはともかくとして知っている人は少ないんじゃないかと思っ たわけです. でも, これって既存クラスへのメソッド追加であって, 新規クラスの場合は関 係なかったですね. >> 2段目: evalを用いれば, 動的に(文字列から)メソッド/クラスを定義できる. >これも「文字列から」という点では eval だけど、「動的に」という点では >eval の特徴ではないですよね。 (中略) >とうコードは成立する。 確かにこれも動的なメソッド定義ですね. 私の表現が悪かったです. 次のメイ ルの最後の例にあるような 動的にメソッド定義文を生成するようなことに evalを用いることができるといいたかったのでした. In [ruby-list :02396 ] the message: "[ruby-list:2396] Re: eval()'s context ", on Mar/20 04:36(+0200) Shin-ichiro Hara writes: (中略) >でも、次の例を考えて石塚さんの言っている意味も >分かった気がしました。 > >$input = "abc" >def bar > print "input = #$input\n" >end >$input = "efg" >bar # => input = efg >$input = "abc" >eval("def bar > print \"input = #$input\n\" >end") >$input = "efg" >bar # => input = abc ところで現在, 私はソケットの通信プロトコルを簡単に定義できて通信が行え るようなライブラリを作成中なのですが, その中の機能の一つとしてプロトコ ル仕様をpack/unpackのフォーマットの拡張として与えると, ソケットの read/writeのrubyメソッドを動的に生成するような機能があります. 例えば, "na$1"という拡張フォーマットは, $1は最初の"n"の中身を意味して います. つまり, [size|size長の文字列] というプロトコルを意味しています. "na$1" から 次のような ruby関数の文字列を生成します. def self.get v1, = read(2).unpack(n) v2, = read(v1).unpack("a#{v1}") [v1, v2] end で, これを evalして 実際にメソッドを定義しています. この例はevalを用 たかなり動的なメソッド定義の例になっています. とここまでかいていて気づきましたが... 新しいeval()では, 特異メソッドの定義はできなくなるなんてことはないです よね?? つまり: class Foo def foo eval "def self.bar ... end" end end f = Foo.new f.foo と実行すると, f.bar() はちゃんと定義されますでしょうか?? evalの中では名前空間が変わっているだけで変数のバインディングは変更がな いので問題ないのかなあ?? __ .....................................石塚 圭樹@SHLジャパン(株)... ------------->アドレス変わりました!! e-mail: keiju@shljapan.co.jp <----