Happy birthday Ruby! Let's get lost in the JavaScript world!

Feb 24, 2013

Happy birthday Ruby! It's 24th in the US now, while it is still 24th in Japan. So it is neither too early nor to late:) It is also a perfect chance(and a happy coincidence, I didn't plan to release on this day, it just happens) to show you some of my latest work. The result looks like this:

A live demo is at here. This is the WebGL geometries example at here provided in the three.js repository. While the original example is written in JavaScript, I took some time(actualy less than an hour) to port it to Ruby. The Ruby source code and original JavaScript source code are at here. However, feel free to dig into your favourite developer tools for the demo listed above, since the Ruby code is stored in a separate file, fetched using Ajax and parsed on the fly.

From a comparison of the two versions of source code you can see that a lot of things can be achieved purely in the Ruby side:

Basically most of the things you normally do in JavaScript can be done entirely in Ruby. However, there're still some syntax differences:

object_create_func = $three.SceneUtils.createMultiMaterialObject

However, to invoke this function, you need to use following syntax:

object = object_create_func[$three.CubeGeometry.invoke_new(100, 100, 100, 4, 4, 4), materials]

This is now only a temporarily solution, I may find a way to work around this.

foo.call(:set, 1)
# or
foo[:set].invoke(1)
p = Proc.new {
 puts "Resize occurs!"
}
$window.addEventListener('resize', p, false)

You can also use existing functions as callbacks, but do remember you need to use the following syntax:

def onResize
 puts "Resize occurs!"
end
$window.addEventListener('resize', :onResize.to_proc, false)

While we still use a symbol to represent a function, to_proc must be invoked to tell webruby that we want to use the actual function, not the onResize string.

And there's one more TODO task: currently you cannot pass arguments to a callback function using a Ruby proc. For example, if you add arguments to window.setInterval, they are not passed back to your Ruby Proc. I will work on this in the next few days(but not today, I have some stupid homework to finish today-_-).

Although we have a few limitations or rules to keep in mind, I do think we now have a almost complete JavaScript calling interface:) Now we have a whole lot of existing JavaScript libraries that we can take advantage of, including three.js, the yet-to-release famo.us engine and WebAudio.js, etc. We may even take advantage of the WebWorker API for multi-threading! I must admit that I'm a little behind schedule for my OpenGL ES binding project, but since we have three.js now, we can already create awesome Web projects:) Anyway, I will come back to create a complete OpenGL ES binding implemention.

Ruby: will you love your new JavaScript house in the next 20 years? I do wish you enjoy it!