From: 7stud -- Date: 2009-09-19T11:10:34+09:00 Subject: Re: Mucking about with dynamically adding methods to objects Paul Smith wrote: > I think I have a lot more reading to do before >>irb(main):014:2> (class << obj;self;end).instance_eval do >>irb(main):015:3* define_method :talk do > makes any kind of sense. I just started chapter 14 of the "The Well Grounded Rubyist", and instance_eval() and define_method() are explained in regards to a similar example. Something that bothered me when I initially read that code was the use of instance_eval(). I was left wondering why the more natural-reading class_eval() wasn't used? After all, the goal is to create a method in the singleton *class*. You can do this with class_eval(): class FairyGodmother def get_singleton_class(obj) class << obj self end #explained on p.392 end def talkify(obj, str) obj_singleton = get_singleton_class(obj) obj_singleton.class_eval %Q{ def talk puts "hello" end } end end ...but if you try this: def talkify(obj, str) obj_singleton = get_singleton_class(obj) obj_singleton.class_eval %Q{ def talk puts str #<---CHANGE HERE**** end } end ...it doesn't work. The def creates a new scope, and str is not defined inside the def. Using a string as an argument for class_eval() is unwieldy. Luckily, class_eval() will take a block--instead of a string: def talkify(obj, str) obj_singleton = get_singleton_class(obj) obj_singleton.class_eval do def talk puts 'hello' end end But once again, the def creates a new scope, so the code inside the def can't reference variables outside the def--like str(which is one of talkify()'s parameter variables). define_method() to the rescue: def talkify(obj, str) obj_singleton = get_singleton_class(obj) obj_singleton.class_eval do define_method("talk") do puts str end end Neither of the blocks used with class_eva() or define_method() creates a new scope, so code inside them can make use of variables defined in the surrounding scope. Anyway, after working through that example, I wonder if there is a difference between instance_eval() and class_eval() when the receiver is a class? -- Posted via http://www.ruby-forum.com/.