Adding methods at runtime in javascript, ruby, and java
OK, the title is a ruse, you can't easily add methods to java classes at runtime. But I'll illustrate how to do it in javascript and ruby. For example, lets supposed we have a javascript object(function) and we want to add a say_hello method to it:
This is because javascript treats functions as first class citizens and doesn't even bother with the concept of "classes" as something other than special functions.
Same thing in ruby:
There's a subtle difference here. The ruby syntax seems a little strange to me and it wasn't obvious how to do this. In javascript, it's very obvious that you're assigning a new function to the attribute (that you're adding). In ruby, using def in this manner seems out of place...
Ruby seems to attribute special meaning to the class and object definition where javascript treats methods (functions) just like any other variable.
Digging around a little, the ruby situation gets a little strange:
If I want, I COULD have added the method to the class in ruby and then every instance would get it e.g.
It really depends on if you want to "backport" new methods to all objects of a class or only add the method to a particular instance. To do the equivalent in javascript, you'd do something like
The difference between how the two languages accomplish this is pretty minor, the more important thing to understand is the difference between adding a method to and instance (object) or a class definition(prototype). Not having a complete understanding of these differences can cause a lot of problems and subtle bugs in your code.
var myObj = {}; myObj.say_hello() // doesn't work myObj.say_hello = function() { return "hello"; } myObj.say_hello(); //works
This is because javascript treats functions as first class citizens and doesn't even bother with the concept of "classes" as something other than special functions.
Same thing in ruby:
myObj = Object.new myObj.say_hello # doesn't work def myObj.say_hello "hello" end myObj.say_hello # works
There's a subtle difference here. The ruby syntax seems a little strange to me and it wasn't obvious how to do this. In javascript, it's very obvious that you're assigning a new function to the attribute (that you're adding). In ruby, using def in this manner seems out of place...
Ruby seems to attribute special meaning to the class and object definition where javascript treats methods (functions) just like any other variable.
Digging around a little, the ruby situation gets a little strange:
myObj2 = Object.new; myObj2.say_hello @ doesn't work (this makes sense because we only defined the method on one instance Object.respond_to? :say_hello #false ??? I "kinda" get it myObj.respond_to? :say_hello #nil ??? OK, now I'm pretty confused
If I want, I COULD have added the method to the class in ruby and then every instance would get it e.g.
myObj = Object.new() myObj.say_hello # doesn't work class Object def say_hello "hello" end end myObj.say_hello # works myObj2 = Object.new() myObj2.say_hello #works MyThing.respond_to? :say_hello #works
It really depends on if you want to "backport" new methods to all objects of a class or only add the method to a particular instance. To do the equivalent in javascript, you'd do something like
var myObj = {}; myObj.say_hello() // doesn't work Object.prototype.say_hello = function() { return "hello"; } myObj.say_hello(); //works var myObj2 = {}; myObj2.say_hello() //works (new Array()).say_hello() //works!
The difference between how the two languages accomplish this is pretty minor, the more important thing to understand is the difference between adding a method to and instance (object) or a class definition(prototype). Not having a complete understanding of these differences can cause a lot of problems and subtle bugs in your code.
Comments