Update: I've changed the API a little bit. Please check this post for the latest API. I decided to keep this post unchanged so you can see both versions. Feel free to leave a comment if you belive the old one is better:)
Lately some people have been asking me to write a tutorial on how to use Webruby. Sorry, guys. I was having a lot of fun writing this stuff but I forgot to bring these fun to you. Now the tutorial on Webruby is finally here:)
The final result of this tutorial looks like this:
First question: where do I put my Ruby source code?
Before everything starts, we need a place to keep and load our Ruby source code. Webruby now supports 3 kinds of source code loading methods:
All the source code in
appfolder of Webruby will be compiled and attached in the
mruby.jsfile automatically. Then we can use
WEBRUBY#runto load this part of source code.
WEBRUBY#run_bytecodeto execute the bytecode directly. With this method, you can get the flexibility of loading code on the fly, while avoiding parsing Ruby source code at the browser side(and the whole parsing part can be avoided in
And of course, you can use
WEBRUBY#run_sourceto parse and execute Ruby code directly.
Webruby allows you to specify the loading modes you will use when compiling, this can help reduce the size of
mruby.js file: if you do not need to parse Ruby source code on the fly, you wouldn't need all the parsing code in the generated
mruby.js file, and if you only execute source code from
app folder, modern optimizers may take advantage of that to further reduce the file size. Please refer to
rakelib/functions.rb for how to specify supported loading modes. In this tutorial, we will use the default loading modes, which will support all 3 kinds of loading methods. And we will show how to load Ruby source code using
WEBRUBY#run_source. The second method describes above is a little bit of complicated(since mruby has multiple versions of bytecode), I will describe it in another post(maybe with specialized bytecode generation tools) later.
Okay, I got that. But how to run this stuff exactly?
Now we've got all the backgrounds needed, let's walk through the developing process step by step.
I assure you that this is easy to do. Just clone the [project](https://github.com/xxuejie/webruby] from Github and setup submodules:
And do remember one thing: webruby uses emscripten, and emscripten uses LLVM internally. So you may also need to install LLVM:
Note this is the Mac-with-homebrew way of installing LLVM. If you know how to install LLVM 3.2 on Linux/Windows, I will really appreciate it if you can comment below, I will update this post accordingly.
Update: Thanks to Reed for pointing out, actually you can just go to http://llvm.org/releases/download.html, download and extract the pre-compiled binary for your platform, change the value of
LLVM_ROOT in your
~/.emscripten file to match the bin directory of your LLVM installation. You are then good to go!
This is almost it! I guess I may assume that most of you have Ruby and node.js installed already. But if you are not so convinced, you can run the mruby unit tests in webruby environment:
If you can see this, everything is fine:)
Webruby is designed in a way that the core project just contains build scripts and a very small yet required driver code. The rest parts are in separate projects(organized as mrbgems). The idea here is that your final
The latest mruby supports using mrbgem directly from a git repository, so all you need to do here is uncomment Line #32 in
build_config.rb. And make it look like this:
Notice that if you have run
mrbtest before uncommenting this line, you need to run
rake clean to cleanup everything and do a full rebuild. This is due to that the gem settings have changed.
Writing Webruby code
Now we can actually start writing Ruby code. First we will try the first loading method: all the source code in
app folder of webruby will be compiled and then attached in the
mruby.js file. So feel free to add or change any file in the folder, but please do remember to add
A special file named
app.rb will be compiled at last, it serves as the entrypoint(or so-called "main" file). For our simplest demo, we will just code in this file. Now you can bring out your favourite code editor and change the content of this file to:
There is only one method in module
get_root_object. It would return the
window object for a browser environment, or the
global object when running in node.js. The returned object is of class
JsObject also comes with
call_constructor function for making a new call, and
get for getting a field value from an object. Note that
mruby-js is still under development, function and array passing support is still lacking, and the APIs are subject to change. I will try my best to keep here updated, but please always use the source code as the answer if you find a disagreement.
Now you can compile webruby using
rake, if everything works well(it should), you can find a
mruby.js file in
Node.js is great for debugging, but I believe most of you want to use webruby in a browser enviroment. We also need an HTML skeleton for loading our generated JS file.
Here's a sample skeleton: note that this only serves as a sample, and I believe all of you can write a much better skeleton within seconds. But for now, please bear with this dumb one:
Put this html file in the same folder with
mruby.js file and open it with a modern browser, you can see an initial result:)
Loading Ruby source code on the fly
By changing the value of environment variable
LOADING_MODE, you can actual customize the loading methods you want to support. For example, the following line can be used to only allow for running attached Ruby code compiled from
If you have been following this post, then your
mruby.js must have already contained parsing code. Otherwise you may want to use following command to rebuild the JS file:
Now it looks just like what is shown in the demo. You can also use Closure Compiler to strip the size of generated JS file if you like, but please keep in mind that only simple optimization works for now, the advanced option still needs a little tweaking. On my machine, with a simple optimization the size of the JS file can be reduced from 4.2MB to 1.5MB.
It really feels nice to finally have something for everyone to use:) I've had a lot of fun and I will be continue maintaining this. Of course this is not fit for everyone's project, even after optimization there's a 1.5MB JS file to load. For now I guess the most suitable use case will be Web games or single page apps. This is why I'm also working on an OpenGL ES 2.0 binding. Anyway, I wish all of you had fun playing with webruby, just like I had fun developing this:)