よたらぼ
自分の興味の赴くままにIT技術系のネタを取りとめもなくメモっています。
Ruby言語やLinuxのネタが多いです。

October 13, 2003 [おもひで]

[Ruby] Object#instance_eval(2)

MLに送ったら新井さんに2つほど解決策を教えていただいた。感謝です。

(案1) 引数となる文字列側で対処

class Test
   def initialize(m)
      instance_eval(m)
   end
end
 
a = Test.new(%Q[
    def hoge
      p "hoge"
    end
 
    def foo
      p "foo"
    end
 
    class <<self
    private :foo
    end
])

(案2) 受け側で対処

class Test
   def initialize(m)
     eval("class <<self;" + m + "\nend")
   end
end
 
a = Test.new(%Q[
    def hoge
      p "hoge"
    end
 
    private
    def foo
      p "foo"
    end
])

今回は引数は別ファイル化する予定なので渡す側がRubyでの使い方により近い(案2)を使おうと思います。

ちなみに、ZnZさんにもコメントを頂きました。Moduleのメソッドであっても呼べるのかと思ってました。instanceのevalだから呼べないのか。

新井さんのコメントに

「instance_evalでメソッド定義できるのが異端とも言える。」

というのがあったのだけどつまりはそういうことか...。うーんうーん。

#まだよくわかってないらしい(^^;)。

本日のツッコミ(全3件) [ツッコミを入れる]
arai (October 16, 2003 05:30)

つまり、ある例外を除けばメソッド定義はselfがクラスのときしか
できないように(rubyレベルでは)見えるということです。
例外というのはトップレベルと instance_eval の二つ(それ以外であるかなあ?)で
ここから instance_eval は異端と言いました。
さて問題、トップレベルで private が呼べる理由は?答えはリファレンスの
用語集(mainの項)にあり。

arai (October 16, 2003 05:39)

あっ1.8でメソッド定義がネストできるようになったのと def obj.m 形式はど
こでも書けるからやっぱ self がクラスのときだけというのは無理があった。
穴だらけ(汗

むとぽん (October 16, 2003 22:31)

なるほど。
「(例外はあるけど)selfがクラスのときのみメソッドを定義できる」
ということですね。

ところで、トップレベルでpublicとprivateが呼べる理由って何でしょう。ってか、トップレベルでpublicとかprivateとかって区別する必要があるのかな。
#いや、リファレンスの用語集(mainの項)には見あたらなかったので...。


編集