From: Rick DeNatale Date: 2006-09-29T06:30:56+09:00 Subject: Re: define_method confusery On 9/28/06, Martin Coxall wrote: > On 9/28/06, Arnaud Bergeron wrote: > > > > On 9/28/06, Martin Coxall wrote: > > [snip] > > > > > > # List the methods of Klass > > > Klass.methods.sort.each do |method| > > > > Try Klass.instance_methods. > > > Aha! That would do it. Thanks. > > Do you know if it's possible to add class methods to classes using > define_method() then? It seems to work if I do a > > define_method("Klass."+methodName) > > However, when I then try to invoke using > > Klass.send(methodName, "some stuff") > > It doesn't work. You need to send define_method to the classes singleton class, and that takes a trick: rick@frodo:/public/rubyscripts$ cat def_class_meth.rb #! /usr/bin/ruby # def create_method(name, klazz, meth = nil, &b) raise ArgumentError "give method or block, but not both" if meth && block_given? if block_given? klazz.send(:define_method, name, &b) else klazz.send(:define_method, name, meth) end end def create_class_method(name, klazz, meth=nil, &b) klazz_klazz = class << klazz; self; end create_method(name, klazz_klazz, meth, &b) end class Foo end create_method(:foo_inst_meth, Foo) {"This is an instance method of Foo"} create_class_method(:foo_class_meth, Foo) {"This is a class method of Foo"} puts Foo.new.foo_inst_meth puts Foo.foo_class_meth rick@frodo:/public/rubyscripts$ ruby def_class_meth.rb def_class_meth.rb:5: warning: parenthesize argument(s) for future version This is an instance method of Foo This is a class method of Foo rick@frodo:/public/rubyscripts$ Note that in ruby 1.9 send won't call a private method anymore, you need to use funcall instead. http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9#l18 -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/