# Dynamically adding methods to a class

**URL:** <https://www.ruby-forum.com/t/dynamically-adding-methods-to-a-class/188757>\
**Category:** Ruby\
**Created:** [May 18, 2010, 1:25am UTC](https://www.ruby-forum.com/t/dynamically-adding-methods-to-a-class/188757 "2010-05-18T01:25:53Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![finality](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/5f8ce5/32.png) [@finality](https://www.ruby-forum.com/u/finality)\
**Post date:** [May 18, 2010, 1:25am UTC](https://www.ruby-forum.com/t/dynamically-adding-methods-to-a-class/188757/1 "2010-05-18T01:25:53Z")

</div>

Hi!

I’m trying to add a method dynamically to a class by opening an existing  
class, and it actually works. What I don’t understand is why it doesn’t  
show up when I use the “methods” method on it afterwards.

What I do is something like this:  
Code:

def method\_missing name, \*args

Array.class\_eval “def #{name} \*args; #{str}; end”

end

Afterwards I can call that method on every object of this class (new or  
otherwise). However, it doesn’t show up in Array.methods.

The Array.methods.length is the same both before and after that line is  
executed and adds the method. However, if I do a self.methods.length the  
number of methods has increased.

My question is therefore this: how can I add a method to a class (e.g.  
Array) and have it show up when I do a .methods on it?

Thanks in advance for any help!

---

<div class="post-metadata">

**Author:** ![finality](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/5f8ce5/32.png) [@finality](https://www.ruby-forum.com/u/finality)\
**Post date:** [May 18, 2010, 2:40am UTC](https://www.ruby-forum.com/t/dynamically-adding-methods-to-a-class/188757/2 "2010-05-18T02:40:47Z")

</div>

On Mon, May 17, 2010 at 6:25 PM, Sam U. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> My question is therefore this: how can I add a method to a class (e.g.  
> Array) and have it show up when I do a .methods on it?
> 
> ## Thanks in advance for any help!
> 
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

It is not being defined for the Array class, but rather for instances of  
the  
Array class. Try:  
Array.instance\_methods

---

<div class="post-metadata">

**Author:** ![finality](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/5f8ce5/32.png) [@finality](https://www.ruby-forum.com/u/finality)\
**Post date:** [May 18, 2010, 8:16am UTC](https://www.ruby-forum.com/t/dynamically-adding-methods-to-a-class/188757/3 "2010-05-18T08:16:08Z")

</div>

Adding to the Array class’ instance methods:

class Array  
def my\_method  
end  
end

Array.instance\_methods.grep /my\_meth/ # =\> [:my\_method]

Adding to the Array class itself:

class Array

# More than one idiom in use here…

def self.my\_other\_method  
end  
end

Array.methods.grep /my\_oth/ # [:my\_other\_method]

greetings,  
kaspar

---

<div class="post-metadata">

**Author:** ![finality](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/5f8ce5/32.png) [@finality](https://www.ruby-forum.com/u/finality)\
**Post date:** [May 18, 2010, 3:38pm UTC](https://www.ruby-forum.com/t/dynamically-adding-methods-to-a-class/188757/4 "2010-05-18T15:38:45Z")

</div>

On Tue, May 18, 2010 at 9:13 AM, Sam U. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> puts fr.methods.include? “somefunc”  
> puts Fred.new.methods.include? “somefunc”  
> puts Fred.instance\_methods.include? “somefunc”
> 
> Gives the output:
> 
> > > false  
> > > false  
> > > false

Really? I ran your Test.rb program in its entirety and got the  
following output:

inside method\_missing  
1st time - called by the var fr  
2nd time - called by the var fr  
3rd time, this one’s a new instance  
true  
true  
true

–  
Rick DeNatale

Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
Github: [rubyredrick (Rick DeNatale) · GitHub](http://github.com/rubyredrick)  
Twitter: @RickDeNatale  
WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![finality](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/5f8ce5/32.png) [@finality](https://www.ruby-forum.com/u/finality)\
**Post date:** [May 18, 2010, 3:58pm UTC](https://www.ruby-forum.com/t/dynamically-adding-methods-to-a-class/188757/5 "2010-05-18T15:58:04Z")

</div>

On Tue, May 18, 2010 at 3:13 PM, Sam U. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> ^^ Notice how the message “inside method\_missing” only shows up once.  
> Well it is not missing anymore as you define it when it is missing, it  
> is not defined temporarily.
> 
> Everything is OK so far, the method somefunc seems to have correctly  
> added itself as an instance method to the class Fred… but the following  
> confuses me:
> 
> puts fr.methods.include? “somefunc”  
> puts Fred.new.methods.include? “somefunc”  
> puts Fred.instance\_methods.include? “somefunc”  
> And what if you call  
> Fred.new.somefunc  
> first?  
> HTH  
> R

---

<div class="post-metadata">

**Author:** ![finality](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/5f8ce5/32.png) [@finality](https://www.ruby-forum.com/u/finality)\
**Post date:** [May 18, 2010, 3:13pm UTC](https://www.ruby-forum.com/t/dynamically-adding-methods-to-a-class/188757/6 "2010-05-18T15:13:33Z")

</div>

Thanks very much guys!

I’m still confused about this one thing, though.  
Example:  
class Fred

```
def method_missing name, *args
  puts "inside method_missing"

  Fred.class_eval "def #{name} val; puts val; end"
  send(name, args)
end

```

end

fr=Fred.new  
fr.somefunc “1st time - called by the var fr”  
fr.somefunc “2nd time - called by the var fr”  
Fred.new.somefunc “3rd time, this one’s a new instance”

The code above gives the following output:

> > inside method\_missing  
> > 1st time - called by the var fr  
> > 2nd time - called by the var fr  
> > 3rd time, this one’s a new instance

^^ Notice how the message “inside method\_missing” only shows up once.

Everything is OK so far, the method somefunc seems to have correctly  
added itself as an instance method to the class Fred… but the following  
confuses me:

puts fr.methods.include? “somefunc”  
puts Fred.new.methods.include? “somefunc”  
puts Fred.instance\_methods.include? “somefunc”

Gives the output:

> > false  
> > false  
> > false

How is it that none of these can find the method somefunc?  
Could anyone else try this out? I’ve attached the code

---

<div class="post-metadata">

**Author:** ![finality](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/5f8ce5/32.png) [@finality](https://www.ruby-forum.com/u/finality)\
**Post date:** [May 18, 2010, 4:45pm UTC](https://www.ruby-forum.com/t/dynamically-adding-methods-to-a-class/188757/7 "2010-05-18T16:45:21Z")

</div>

Rick Denatale wrote:

> On Tue, May 18, 2010 at 9:13 AM, Sam U. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> wrote:
> 
> > puts fr.methods.include? “somefunc”  
> > puts Fred.new.methods.include? “somefunc”  
> > puts Fred.instance\_methods.include? “somefunc”
> > 
> > Gives the output:
> > 
> > > > false  
> > > > false  
> > > > false
> 
> Really? I ran your Test.rb program in its entirety and got the  
> following output:
> 
> inside method\_missing  
> 1st time - called by the var fr  
> 2nd time - called by the var fr  
> 3rd time, this one’s a new instance  
> true  
> true  
> true
> 
> –  
> Rick DeNatale
> 
> Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
> Github: [rubyredrick (Rick DeNatale) · GitHub](http://github.com/rubyredrick)  
> Twitter: @RickDeNatale  
> WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
> LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

Yup, I run the code in its’ entirety too.  
Perhaps I somehow screwed up my Ruby install?  
I was lazy I admit and didn’t feel like reading up on how to install  
Ruby, so I just DLed the latest one found here:  
[http://rubyinstaller.org/download.html](http://rubyinstaller.org/download.html)

Which version are you using, if you don’t mind me asking?

@Rob: you mean declaring Fred.new.somefunc before fr.somefunc?  
If so, no difference at the end - still just gives me three false.

Thanks guys for your time!

---

<div class="post-metadata">

**Author:** ![finality](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/5f8ce5/32.png) [@finality](https://www.ruby-forum.com/u/finality)\
**Post date:** [May 18, 2010, 5:02pm UTC](https://www.ruby-forum.com/t/dynamically-adding-methods-to-a-class/188757/8 "2010-05-18T17:02:29Z")

</div>

On Tue, May 18, 2010 at 10:45 AM, Sam U. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> Yup, I run the code in its’ entirety too.  
> Perhaps I somehow screwed up my Ruby install?  
> I was lazy I admit and didn’t feel like reading up on how to install  
> Ruby, so I just DLed the latest one found here:  
> [http://rubyinstaller.org/download.html](http://rubyinstaller.org/download.html)
> 
> Which version are you using, if you don’t mind me asking?

I’m guessing you are using Ruby 1.9, which would explain it.

In Ruby 1.9 Object#messages returns an array of symbols, whereas Ruby  
1.8 returns an array of strings.

Try changing those last 3 lines to:

## puts fr.methods.include? :somefunc puts Fred.new.methods.include? " :somefunc puts Fred.instance\_methods.include? :somefunc

Rick DeNatale

Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
Github: [rubyredrick (Rick DeNatale) · GitHub](http://github.com/rubyredrick)  
Twitter: @RickDeNatale  
WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![finality](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/5f8ce5/32.png) [@finality](https://www.ruby-forum.com/u/finality)\
**Post date:** [May 18, 2010, 6:24pm UTC](https://www.ruby-forum.com/t/dynamically-adding-methods-to-a-class/188757/9 "2010-05-18T18:24:03Z")

</div>

That worked perfectly!  
Many, many thanks to you! 🙂
