1

I want to create a function that messes around with the classes passed to it. What would be the most idiomatic way to reopen those classes to add functionality? Here's what I mean:

def class_messer(target_object)
  #would like to reopen class here with something like:
  class target_object.class
    #add methods
  end
end

Obviously that syntax doesn't work. I could get the target_object's class and eval some strings, but that feels gross. Is there a more idiomatic way to do this?

TG-T
  • 2,174
  • 3
  • 19
  • 20

4 Answers4

5

I think you're looking for class_eval. If you want to reopen a class and you do not have the constant as is, but a reference, you can call class_eval on it and pass a block (or even a string) of code to be evaluated in that classes context.

def class_messer(target_object)

  # assuming that target_object is an instance of desired class

  target_object.class.class_eval do
    #add methods
  end

end
Radi
  • 696
  • 4
  • 11
2
target_object.class.class_exec do
  # add methods
end
Mori
  • 27,279
  • 10
  • 68
  • 73
2

Maybe it's not correct to change class, for example, if you had an instance of Array class and changed its class, then this change could impact on other instances of Array class. So instead use singleton class of instance and the definition of method will be:

target_object.send(:define_method, :new_method) do
  #... 
end

or

class << target_object
  def new_method
    #...
  end
end
Community
  • 1
  • 1
megas
  • 21,401
  • 12
  • 79
  • 130
0

You can also do this:

class << target_object.class

end
Radu Stoenescu
  • 3,187
  • 9
  • 28
  • 45