An Introduction to Mini Ruby

An Introduction to Mini Ruby

Ruby is used in a wide variety of projects today, but has gained popularity in web development with Ruby on Rails. With mruby, the latest language implementation, Ruby can be embedded into other applications.

Installation

The mruby project is hosted on Github. There are currently no binary distributions available, but it is easy enough to build mruby from source. mruby uses the bison parser generator, which we need to install before we can build from source.

apt-get install bison build-essential

Make sure you have Git installed on your system and then execute the following commands:

git clone git://github.com/mruby/mruby.git
cd mruby
make

This will clone the repository from Github and compile mruby. After compilation has finished, you should have the mruby binaries in bin/, library files in lib/ and header files in include/.

Executables

The compilation process generates three binaries in the bin/ directory. Lets inspect them one by one.

mruby

This is the equivalent to the normal Ruby binary your have with MRI Ruby. You can execute mruby scripts or just check them for syntax errors.

mirb

mirb is the mruby variant of the interactive ruby shell, you probably already know from standard Ruby. It provides an easy and interactive interface where you can write ruby code and execute it on-the-fly.

$ ./mirb 
mirb - Embeddable Interactive Ruby Shell

This is a very early version, please test and report errors.
Thanks :)

> s = "awesome"
 => "awesome"
> p "Ruby is #{s}"
"Ruby is awesome"
 => "Ruby is awesome"

mrbc

The mrbc binary is the mruby bytecode compiler. It translates mruby scripts into either rite bytecode for the RiteVM (which is the name of the VM mruby uses) or transforms it into a C program. While mruby can directly execute Ruby scripts you can use mrbc to precompile the scripts into bytecode. This obviously makes execution of your programs faster, as the script does not have to be parsed every time you want to execute it.

Say you have a script called test.rb and want to compile it to bytecode and then execute it with mruby. All you need to do is the following:

./bin/mrbc test.rb
./bin/mruby -b test.mrb

Embedding mruby

mruby is designed to be embedded into other applications. It provides an easy to use C API which can be used to execute scripts or simply hard-coded strings or to extend mruby by providing custom classes that interface with your application. A "Hello World" like example for the C API is the following:

#include <stdlib.h>
#include <stdio.h>

#include <mruby.h>
#include <mruby/compile.h>

int main(void)
{
  mrb_state *mrb = mrb_open();
  char code[] = "5.times { puts 'Ruby is awesome!' }";

  mrb_load_string(mrb, code);
  return 0;
}

This small snippet creates a new instance of mruby using mrb_open (defined in mruby.h) and then loads and executes the character array with ruby code using mrb_load_string. In order to compile this code we need to tell gcc, to link the libmruby library. We also need to include the math library (-lm) which is not linked with libmruby.

$ gcc -Iinclude main.c lib/libmruby.a -lm -o main.out
$ ./main.out
Ruby is awesome!
Ruby is awesome!
Ruby is awesome!
Ruby is awesome!
Ruby is awesome!

There are several ways by which you can optimize mruby itself. For one you can force the mruby runtime to use float instead of double values for representing floating point number by simply defining the MRB_USE_FLOAT constant as compiler option (-DMRB_USE_FLOAT). Other options can be found in include/mrbconf.h:

/* -DDISABLE_XXXX to drop the feature */
#define DISABLE_REGEXP          /* regular expression classes */
//#define DISABLE_SPRINTF       /* Kernel.sprintf method */
//#define DISABLE_MATH          /* Math functions */
//#define DISABLE_TIME          /* Time class */
//#define DISABLE_STRUCT        /* Struct class */
//#define DISABLE_STDIO         /* use of stdio */

By default only regular expressions are disabled.

Limitations

mruby comes with a number of limitations to make it as light as possible. The probably most notable feature that has been left out, is the ability to require files. Requiring other files is an expensive operation and does not fit well into the design of mruby. Similarly forks and threads are not available for mruby scripts.

Conclusions

mruby is still in development, but there already are a number of good projects utilizing it. MobiRuby brings mruby to the iOS platform and allows you to build apps for mobile devices. mruby has a low-memory footprint and is in many ways similar to Lua. Lua is extensively used in scripting video games or as a way to influence httpd request processing in popular webservers like Apache, lighttpd or NginX. For Apache, there already is a mod_mruby that is developed as an alternative to Lua.

Additional Ressources