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.
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.
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.
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 .
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.
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"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With