Rubyで動的に関数定義  [ruby]  [tips]

module_eval(= class_eval),instance_evalがある。
なんで、この機能を調べているかというと、Railsで試験しているときに、ログインユーザを切り替えようと、一つのテスト関数内でログインを繰り返してたら、同じテスト関数内は同一セッションになって「すでにログインしてます」とかなったわけさ。(俺のインプリでは)


で、いちいちログアウトさせるのも面倒なので、いっそのことテスト関数を自動生成しようと思った。


そのうち詳しく書こうと思うので[todo]タグ。


追記:


module_eval(=class_eval)は、レシーバのクラスにインスタンス関数を定義。


irb> class Hoge
irb> end
irb> hoge = Hoge.new
irb> Hoge.module_eval {def fuga() p 'fuga';end}
irb> Hoge.fuga #=> error
irb> hoge.fuga #=> 'fuga'
irb> Hoge.new.fuga #=> 'fuga'



instance_evalは、レシーバがクラスの場合、クラス関数を定義(def self.xxxってやるやつと同等)


irb> class Hoge
irb> end
irb> hoge = Hoge.new
irb> Hoge.instance_eval {def fuga() p 'fuga';end}
irb> Hoge.fuga #=> 'fuga'
irb> hoge.fuga #=> error
irb> Hoge.new.fuga #=> error

instance_evalは、レシーバがobjectのインスタンス場合、そのobjectのインスタンス関数を定義


irb> class Hoge
irb> end
irb> hoge = Hoge.new
irb> hoge.instance_eval {def fuga() p 'fuga';end}
irb> Hoge.fuga #=> error
irb> hoge.fuga #=> 'fuga'
irb> Hoge.new.fuga #=> error



これに変数のスコープとからむとさらにややこしそうだ。
そのうち調べよう。ということでまだ[todo]

追記:
Rubyで動的に関数定義2
Rubyで動的に関数定義3(for Test::Unit)