Dynamically adding methods to a class

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 <class>.methods on it?

Thanks in advance for any help!

···

--
Posted via 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

···

On Mon, May 17, 2010 at 6:25 PM, Sam Uel <cannedlobstah@gmail.com> wrote:

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 <class>.methods on it?

Thanks in advance for any help!
--
Posted via http://www.ruby-forum.com/\.

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

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

Attachments:
http://www.ruby-forum.com/attachment/4740/Test.rb

···

--
Posted via http://www.ruby-forum.com/\.

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

···

On Tue, May 18, 2010 at 9:13 AM, Sam Uel <cannedlobstah@gmail.com> wrote:

puts fr.methods.include? "somefunc"
puts Fred.new.methods.include? "somefunc"
puts Fred.instance_methods.include? "somefunc"

Gives the output:

false
false
false

--
Rick DeNatale

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

^^ 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

···

On Tue, May 18, 2010 at 3:13 PM, Sam Uel <cannedlobstah@gmail.com> wrote:

--
The best way to predict the future is to invent it.
-- Alan Kay

Rick Denatale 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/
Github: http://github.com/rubyredrick
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: 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

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!

···

On Tue, May 18, 2010 at 9:13 AM, Sam Uel <cannedlobstah@gmail.com> > wrote:

--
Posted via http://www.ruby-forum.com/\.

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

···

On Tue, May 18, 2010 at 10:45 AM, Sam Uel <cannedlobstah@gmail.com> 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

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

--
Rick DeNatale

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

That worked perfectly!
Many, many thanks to you! :slight_smile:

···

--
Posted via http://www.ruby-forum.com/.