Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 375
eonil Avatar asked Nov 12 '11 13:11

eonil


People also ask

How to define method dynamically in Ruby?

define_method is a method defined in Module class which you can use to create methods dynamically. To use define_method , you call it with the name of the new method and a block where the parameters of the block become the parameters of the new method.

What is MetaProgramming in Ruby?

Metaprogramming is a technique in which code operates on code rather than on data. It can be used to write programs that write code dynamically at run time. MetaProgramming gives Ruby the ability to open and modify classes, create methods on the fly and much more.

What is Instance_eval Ruby?

instance_eval is a similar method on the Object class that takes in Ruby code embedded in a string and two other optional arguments. One of the major differences between eval and instance_eval is that with instance_eval you have the choice of explicitly handling the context of self .


2 Answers

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.

like image 160
tokland Avatar answered Oct 04 '22 22:10

tokland


There's difference between JavaScript and other languages because JavaScript does inheritance in another way. So here's couldn't be direct analogue.

Let's pretend that {} is the A class in ruby and you create object from it

class A
end

a = A.new

And f1 function seats in some module B

module B
  def f1
    puts "you've extended your object"
  end
end

Now you can do what you want in similar way

a.extend(B)

a.f1 #=> "you've extended your object"
like image 39
megas Avatar answered Oct 04 '22 21:10

megas