In how many ways can methods be added to a ruby object?
Asked Answered
P

3

5

When it comes to run time introspection and dynamic code generation I don't think ruby has any rivals except possibly for some lisp dialects. The other day I was doing some code exercise to explore ruby's dynamic facilities and I started to wonder about ways of adding methods to existing objects. Here are 3 ways I could think of:

obj = Object.new

# add a method directly
def obj.new_method
  ...
end

# add a method indirectly with the singleton class
class << obj
  def new_method
    ...
  end
end

# add a method by opening up the class
obj.class.class_eval do
  def new_method
    ...
  end
end

This is just the tip of the iceberg because I still haven't explored various combinations of instance_eval, module_eval and define_method. Is there an online/offline resource where I can find out more about such dynamic tricks?

Pendergrass answered 13/6, 2011 at 6:0 Comment(0)
H
4

Ruby Metaprogramming seems to be a good resource. (And, linked from there, The Book of Ruby.)

Hudgins answered 13/6, 2011 at 6:59 Comment(0)
R
3

If obj has a superclass, you can add methods to obj from the superclass using define_method (API) as you mentioned. If you ever look at the Rails source code, you'll notice that they do this quite a bit.

Also while this isn't exactly what you're asking for, you can easily give the impression of creating an almost infinite number of methods dynamically by using method_missing:

def method_missing(name, *args)
  string_name = name.to_s
  return super unless string_name =~ /^expected_\w+/
  # otherwise do something as if you have a method called expected_name
end

Adding that to your class will allow it to respond to any method call which looks like

@instance.expected_something
Rosalindrosalinda answered 13/6, 2011 at 8:24 Comment(0)
C
2

I like the book Metaprogramming Ruby which is published by the publishers of the pickaxe book.

Casing answered 14/6, 2011 at 0:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.