# Define\_method confusery

**URL:** <https://rubytalk.org/t/define-method-confusery/31426>\
**Category:** ruby-talk\
**Created:** [28 September 2006 16:09 UTC](https://rubytalk.org/t/define-method-confusery/31426 "2006-09-28T16:09:12Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Martin\_Coxall1](https://avatars.discourse-cdn.com/v4/letter/m/f475e1/32.png) [@Martin\_Coxall1](https://rubytalk.org/u/Martin_Coxall1)\
**Post date:** [28 September 2006 16:09 UTC](https://rubytalk.org/t/define-method-confusery/31426/1 "2006-09-28T16:09:12Z")

</div>

So I have some code which adds a method to a class based on user input like  
this:

> **···**
>
> ----------------------------------------------------------------
> 
> class Klass  
> # Do nowt originally  
> end
> 
> # Get the name of a method to add  
> puts "Enter the name of the method to add"  
> $stdout.flush
> 
> methodName = gets  
> methodName.chomp!
> 
> puts "Adding method #{methodName}"  
> $stdout.flush
> 
> # Add a method called 'methodName' to Klass  
> Klass.class\_eval do  
> &nbsp;&nbsp;define\_method(methodName) do |\*values|  
> &nbsp;&nbsp;&nbsp;&nbsp;puts "Welcome to #{methodName}!"  
> &nbsp;&nbsp;&nbsp;&nbsp;puts values.to\_s  
> &nbsp;&nbsp;end  
> end
> 
> # Try to invoke the new method  
> instance = Klass.new  
> instance.send(methodName, "---", "+++")
> 
> # List the methods of Klass  
> Klass.methods.sort.each do |method|  
> &nbsp;&nbsp;puts "Klass##{methodName}"  
> end
> 
> ----------------------------------------------------------------
> 
> So, the code appears to work fine, in that the send() method is able to call  
> the newly created method. So, does anyone know why is it when I list the  
> methods of the class Klass afterwards, the new method does not appear?
> 
> Also, is it possible to use define\_method() to add class methods to classes,  
> rather than just instance methods? I can't seem to get it to work.
> 
> Regards,
> 
> Martin

---

<div class="post-metadata">

**Author:** ![Arnaud\_Bergeron](https://avatars.discourse-cdn.com/v4/letter/a/a183cd/32.png) [@Arnaud\_Bergeron](https://rubytalk.org/u/Arnaud_Bergeron)\
**Post date:** [28 September 2006 16:15 UTC](https://rubytalk.org/t/define-method-confusery/31426/2 "2006-09-28T16:15:15Z")

</div>

[snip]

> # List the methods of Klass  
> Klass.methods.sort.each do |method|

Try Klass.instance\_methods.

> **···**
>
> On 9/28/06, Martin Coxall \<pseudo.meta@gmail.com\> wrote:
> 
> > &nbsp;&nbsp;puts "Klass##{methodName}"  
> > end
> > 
> > ----------------------------------------------------------------

---

<div class="post-metadata">

**Author:** ![Martin\_Coxall1](https://avatars.discourse-cdn.com/v4/letter/m/f475e1/32.png) [@Martin\_Coxall1](https://rubytalk.org/u/Martin_Coxall1)\
**Post date:** [28 September 2006 16:22 UTC](https://rubytalk.org/t/define-method-confusery/31426/3 "2006-09-28T16:22:01Z")

</div>

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.

Regards,

Martin

> **···**
>
> On 9/28/06, Arnaud Bergeron \<abergeron@gmail.com\> wrote:
> 
> > On 9/28/06, Martin Coxall \<pseudo.meta@gmail.com\> wrote:  
> > [snip]  
> > \>  
> > \> # List the methods of Klass  
> > \> Klass.methods.sort.each do |method|
> > 
> > Try Klass.instance\_methods.

---

<div class="post-metadata">

**Author:** ![Rick\_DeNatale1](https://avatars.discourse-cdn.com/v4/letter/r/bbce88/32.png) [@Rick\_DeNatale1](https://rubytalk.org/u/Rick_DeNatale1)\
**Post date:** [28 September 2006 21:30 UTC](https://rubytalk.org/t/define-method-confusery/31426/4 "2006-09-28T21:30:56Z")

</div>

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

> **···**
>
> On 9/28/06, Martin Coxall \<pseudo.meta@gmail.com\> wrote:
> 
> > On 9/28/06, Arnaud Bergeron \<abergeron@gmail.com\> wrote:  
> > \>  
> > \> On 9/28/06, Martin Coxall \<pseudo.meta@gmail.com\> 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.
> 
> #
> 
> def create\_method(name, klazz, meth = nil, &b)  
> &nbsp;&nbsp;raise ArgumentError "give method or block, but not both" if meth &&  
> block\_given?  
> &nbsp;&nbsp;if block\_given?  
> &nbsp;&nbsp;&nbsp;&nbsp;klazz.send(:define\_method, name, &b)  
> &nbsp;&nbsp;else  
> &nbsp;&nbsp;&nbsp;&nbsp;klazz.send(:define\_method, name, meth)  
> &nbsp;&nbsp;end  
> end
> 
> def create\_class\_method(name, klazz, meth=nil, &b)  
> &nbsp;&nbsp;klazz\_klazz = class \<\< klazz; self; end  
> &nbsp;&nbsp;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](http://eigenclass.org/hiki.rb?Changes+in+Ruby+1.9#l18)
> 
> --  
> Rick DeNatale
> 
> My blog on Ruby  
> [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)

---

<div class="post-metadata">

**Author:** ![Martin\_Coxall1](https://avatars.discourse-cdn.com/v4/letter/m/f475e1/32.png) [@Martin\_Coxall1](https://rubytalk.org/u/Martin_Coxall1)\
**Post date:** [28 September 2006 22:36 UTC](https://rubytalk.org/t/define-method-confusery/31426/5 "2006-09-28T22:36:03Z")

</div>

> You need to send define\_method to the classes singleton class, and  
> that takes a trick:

Okay, I think I understand why that is, but I'd better re-read Programming Ruby on Singleton classes.

> def create\_class\_method(name, klazz, meth=nil, &b)  
> klazz\_klazz = class \<\< klazz; self; end  
> create\_method(name, klazz\_klazz, meth, &b)  
> end

Okay, I can kind of see that. I think. Um.

Thanks very much.

Martin
