From: 7stud -- Date: 2009-09-18T03:11:45+09:00 Subject: Re: Mucking about with dynamically adding methods to objects Paul Smith wrote: > 2009/9/17 Jes�s Gabriel y Gal�n : >>> end >> irb(main):013:1> def talkify(obj,str) >> irb(main):023:0> A.new.talkify o,"hi" >> => # >> irb(main):024:0> o.talk >> hi >> => nil >> >> We call define_method in the singleton class of obj. We need the >> instance_eval because define_method is private. >> >> Hope this helps, >> > > Thanks > > 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. > This isn't going to work: def talkify(obj, str) def obj.talk puts str end end because in ruby nested methods do not form "closures". That means a nested method cannot see the local variables(including the parameter variables) in the enclosing method. However, blocks can see variables in the surrounding scope, for example: def meth x = 10 arr = [1, 2, 3] arr.each{|num| puts num + x} end --output:-- 11 12 13 So that suggests a strategy for devising a solution to your problem: try to employ a block to capture the variables in the surrounding scope instead of a method definition. This is what I came up with: class FairyGodmother def get_singleton_class(obj) class << obj self end end end 1) Inside a class definition, like: class << obj self end and outside any method definitions, self is the class object, which in this case is the singleton class of obj. 2) A class definition actually returns the last statement evaluated inside the class, for instance: return_val = class A 10 end p return_val --output:-- 10 3) A method returns the value of the last statement evaluated in the method. The method get_singleton_class(obj) returns the singelton class of obj because this: def get_singleton_class(obj) class << obj self end end becomes this: def get_singleton_class(obj) obj_singleton end which returns obj_singleton. (See p. 392 in your book if that's not clear.) Then you can define talkify() like this: class FairyGodmother def talkify(obj, str) obj_singleton = get_singleton_class(obj) p = Proc.new {puts str} obj_singleton.send(:define_method, "talk", p) end end fairy = FairyGodmother.new() pinochio = Object.new() fairy.talkify(pinochio, "hello") pinochio.talk --output:-- hello -- Posted via http://www.ruby-forum.com/.