Bookmark this on Hatena Bookmark
Hatena Bookmark - enchant.js on Ruby? An experiment…
Share on Facebook
Post to Google Buzz
Bookmark this on Yahoo Bookmark
Bookmark this on Livedoor Clip
Share on FriendFeed

JavaScript is a terrific programming language, but it has its limits. In particular, class definitions can be a bit troublesome. This bothers more than a few people. enchant.js’s Class.create reduces the problem, but it’s still not ideal.

But Japan has its own kickass programming language: Ruby.

One day I thought to myself: enchant.js is already quite easy to use, but wouldn’t Ruby make it even easier? In order to use Ruby in a browser you can try stuff like JSRuby or HotRuby. Of course you can also use JRuby in Java and express as an applet, but this won’t work on smartphones.

In both cases there doesn’t appear to be a prototype out yet. However, it appears that JSRuby attempts to use the Ruby interpreter in JavaScript, and that HotRuby uses YARV from Ruby 1.9 in JavaScript, with the Ruby compiler on the server.

JSRuby still lacks some essential constructions, and the appeal of Ruby doesn’t fully come through. With that in mind, this time I used HotRuby and tried to see what would happen when I plugged enchant.js into it.

For starters, I installed HotRuby to the server. For HotRuby to work I had to first install Ruby 1.9.0. It had to be 1.9.0, specifically. Otherwise, VM: Instruction will not be available for use.

This is an important class that calls up the YARV compiler from Ruby. After this, all I had to do was install HotRuby on the web server.

Next up was the actual Ruby code connecting. This turned out to be rather tricky.

In the case of HotRuby, you first send the Ruby code to the server, compile and receive the YARV interim code. We’re still at the testing stage now, so I decided to basic enchant.js initialization on the JavaScript side.

 enchant(); //Initialize enchant.js
window.onload=function(){
game = new Game(320,320);
game.preload("andy.gif"); //Load Android image
game.onload = function(){
andy = new Sprite(16,16); //Make Android sprite
andy.image = game.assets["andy.gif"];
andy.setXY = function(x,y){this.x=x;this.y=y;} //Make setter to easily call up from Ruby
game.rootScene.addChild(andy);
ruby = new HotRuby(); // Initialize HotRuby
ruby.runFromScriptTag('http://shi3z.yier.in/compileRuby.cgi'); //Call YARV compiler installed in server
setTimeout(function(){ //Executes when compile is finished
game.rootScene.addEventListener('enterframe',function(){
// Directly calls up compiled interim code object
ruby.invokeMethod(ruby.topSF.localVars[2], "enterFrame",
[], ruby.topSF, "VM_CALL_ARGS_SPLAT_BIT" , false);
});
},1000);
}
game.start();
}

When this experimental code is executed, the actual Ruby code should turn out something like what you see below.

<script type="text/ruby"></script>

When executed, I got the following screen.

The Android icon gradually moves to the right as time passes. The Ruby-side “andy” object’s enterFrame method is being called up from game.rootScene.addEventListener(‘enter frame’….) on the JavaScript side.

By the way, HotRuby is quite interesting when considered in the context of a hypothetical Ruby device.

If you display Ruby in the Safari console, you can understand visually how the internal YARV data is put together.

For instance, all classes you create are stored in ruby.classes. If you look into each class in more detail, you find that they are stored in the parent class.

However, because of native access you can access the JavaScript-side object via a global variable called $native.

However, the appeal of enchant.js lies in its callback-based event model. If you want to do callbacks carefully, you’ll probably have a hard time without compensating in HotRuby.js.

It’s necessary to set the Ruby side to “divide up this object, this method, to this event,” and kick this into the JavaScript side.

If you do this, it becomes comparatively easy to use enchant.js on Ruby. Anyone up for the challenge?