rubymetaprogramming

How to add a method to an existing object instance at runtime in Ruby?


In Javascript I could do this.

var a = {};
a.f1 = function(){};

How can I do this in Ruby?


Update.

In JS code, a is an object instantiated without class. And function(){} is an anonymous function, and a.f1 = adds the function to the object instance. So the function is bound to the instance only, and nothing is related to the class or similar definitions.


Solution

  • Ruby and JS's object models are very different, but a direct translation may look like this:

    a = Object.new
    def a.f1(x) 
      2*x
    end
    
    a.f1(5) #=> 10
    

    You can also use the Ruby's eigenclass:

    class Object
      def metaclass
        class << self; self; end
      end
    end
    
    a = Object.new    
    # Also: (class << a; self; end).send(:define_method, :f1) do |x|
    a.metaclass.send(:define_method, :f1) { |x| 2*x }
    

    A warning note: you'll see this kind of code in meta-programming/monkeypatching/... but it's not usual when writing "normal" code, where other techniques (module mix-ins, mainly) apply.