00:00:15.860
Good morning, everybody. As you can see, the title of my talk is '(m)Ruby on Small Devices.' By now, you are all introduced to mRuby.
00:00:21.240
There were two talks on mRuby: one by Eric and one by Kosher. I apologize if I am butchering the name. I did not tell you what mRuby stands for. So, let’s clarify that.
00:00:45.649
mRuby is the minimalistic Ruby, considered as the lightweight sibling of Ruby. It complies with part of the Ruby ISO standard and is sponsored by an institute in Japan. I will follow a convention of using the name 'mRuby' with a capital 'R' to indicate the language and 'mruby' with a lowercase 'r' for the interpreter, just as we do with Ruby.
00:01:15.360
The language is derived from an ISO standard for Ruby, believe it or not. However, mRuby is not Ruby; it is a smaller subset. From my last count of the documentation of mRuby and Ruby, I found that mRuby has about 36 classes and 7 modules, and not all classes have the same list of methods. In comparison, Ruby 2.3 has about 105 classes and 19 modules.
00:01:48.180
The syntax of mRuby is compatible with version 1.9 of Ruby, not with 2.x, because it was conceived before Ruby 2.x was released. The work on mRuby started around 2010, as Matt told me the other day. It has a more liberal license—the MIT license—so you can use it for fun and profit.
00:02:22.530
Now, why should we use something like mRuby? The stated purpose of mRuby is for embedding and linking, especially in the age of small devices. We have devices like Fitbits talking to phones, which in turn connect to the cloud, controlling our Philips Hue lights. These are small devices we want to manage, and using lighter languages is one of the purposes of mRuby.
00:02:52.410
We want to embed and link it, and also because Matt is interested in developing it. Just as there is a rich man named Mitch, we too are nice people working on mRuby.
00:03:19.739
Now, when I refer to 'lightweight,' I mean that it uses less memory during runtime, and the size of the executable must be small enough to fit on small devices. It consumes fewer CPU cycles, making it fast enough to drive devices. It has minimal dependencies on external libraries, which we will explore in the demo part of my session.
00:03:57.570
So, what do we mean by small devices? In this context, I am referring to devices like the Raspberry Pi Zero, which is a single-board computer that costs about five dollars, has a 32-bit single-core CPU, and 512 MB of RAM.
00:04:11.010
We must ensure that everything we do on this tiny computer fits within its constraints. The Raspberry Pi has storage through microSD cards, and we will have a Birds of a Feather session soon where we can hack these Raspberry Pis. I often play with these devices for fun; however, the one I’m using for my demo today is a slightly beefier version because I need to run more intense tasks.
00:04:41.310
This is my first time doing this presentation from a Raspberry Pi running here at the podium. I want to give a huge shoutout to the organizers for accommodating my request and to the AV team for their assistance last night. So, Raspberry Pi is not just for fun; I also use it for profit.
00:05:15.180
I work for a closed-loop credit card company that not many people use unless they have a fleet of trucks or jets. We have fuel cards, and these POS devices are small devices as well. Compared to the Raspberry Pi, they are more bulky and heavier, but in terms of specifications, they operate on a 200 MHz ARM9 32-bit RISC CPU and have only 6 MB of RAM, 2 MB of which is available for my program.
00:06:02.430
Programming on such limited devices is challenging, and my dream is to run mRuby on them. The crux of the issue is that there are not many libraries available for mRuby that run properly on these devices, but with support from the community, I aim to make it happen.
00:06:46.640
Now, this is the company that I work for, Chainlyst. We use a combination of Ruby, Rails, Ember, and Oracle in our stack. If anyone here is interested in a career, we have a 'Now Hiring' link on our website. Please feel free to reach out to me after the talk.
00:07:25.230
Next, let’s discuss embedding and linking. Yesterday's talk highlighted embedding, where you can take a Ruby script and embed it inside C code. Most of the mRuby code I will show today will include some C components.
00:08:01.949
For example, I am creating a string, 'hello world,' loading that string into the mRuby evaluator, which interprets and executes the string, then closes the evaluator.
00:08:45.260
Next, we talk about linking. My system uses GCC as the compiler. Initially, you provide the path to include the mRuby headers required by C code. Expect that this talk engages an audience that understands these concepts, and I will link the Ruby library, 'libmruby,' into my C code, creating an executable that will execute and run the Ruby code embedded inside.
00:09:30.960
To install mRuby, you need some prerequisites. You will need Git, GCC to build mRuby, and a parser generator like Bison on a Linux platform. The issue is that you need Ruby itself to compile mRuby on the device.
00:10:12.600
For most small devices, it can be challenging to have Ruby installed, but for Raspberry Pi, it’s not a problem. I first install Ruby, clone the Git repository, and use 'mini rake' to compile mRuby on my Raspberry Pi.
00:10:48.180
When compiled, mRuby generates various binaries, including the interpreter, which allows interactive sessions similar to Ruby's IRB. The compiler converts the bytecode into a symbol table or an actual executable, and there's even a debugger.
00:11:39.590
For our demo, I’ve prepared a simple Ruby program, 'hello.rb,' which simply outputs 'Hello World.' Compiling it will produce a bytecode file, 'hello.mrb,' which the mRuby compiler can interpret. If you want to examine this file’s contents, you can use the 'hexdump' command.
00:12:48.990
To run this bytecode using mRuby, you need to pass the '-b' flag, ensuring it executes as intended. You can also generate bytecode as a symbol table with the '-B' flag, including that generated file in the C code.
00:13:10.150
The result allows for embedding the mRuby bytecode efficiently within C code. So, how does mRuby generate gems? It has a gem generator called 'mrbgems.' mRuby offers very modular options, allowing you to choose which Ruby parts you want in your compiled version.
00:13:31.760
You can modify the 'build_config.rb' file that comes with the Git repository to include or exclude specific gems, effectively generating an executable that’s personalized for particular needs.
00:14:18.940
The embedded world is often driven by another lightweight embedding language called Lua, which has been around for a long time. Although mRuby is making strides, it's important to note that Lua might outperform mRuby in some contexts due to its simpler design.
00:14:37.080
Lua possesses a prototype-based structure with no classes, making it smaller and faster in certain scenarios. Both languages have similar structures for embedding scripts into C code, demonstrating soft similarity.
00:15:54.909
As we move forward, I will transition to the demo section, and while I showcase mRuby, please feel free to experiment on my Raspberry Pi. I will share the IP address for SSH access, which is 10.35.5.141, and use the password 'RubyConf2016'.
00:17:05.070
I encourage you to look at the Raspberry Pi session and hack it as you please. Please note that this Raspberry Pi will be formatted after the conference. Moving forward in the demo, I want to show you what I mean by lightweight binaries.
00:18:27.669
The mRuby binary size is about 1.5 MB, which is suitable because it must run within a 2 MB limit for my small devices. To check dependencies, using the 'ldd' command reveals its runtime libraries. If you do this for Ruby, you would observe more dependencies.
00:19:30.780
When looking at the sizes, the compiled version can be deceiving, as it may rely on additional libraries. It's crucial to measure both storage size on disk and memory usage when running on devices.
00:20:00.390
Lastly, I'll demonstrate the memory consumption of running Ruby and compare it with mRuby to see how it behaves under limited resources.
00:20:27.780
As you can see, Ruby consumes around 6 MB of RAM, which is not suitable for smaller devices. In contrast, mRuby uses substantially less RAM when running similar programs, making it viable for those environments.
00:21:24.900
Performance benchmarks also show mRuby's speed when executing tasks like calculating Fibonacci numbers. In my experiments, mRuby has particularly behaved favorably in terms of speed compared to Ruby.
00:21:55.230
Another important factor for devices is the speed at which they load applications. I’ll share how various languages perform on this metric, including timing for Ruby, mRuby, Lua, and others.
00:22:35.940
The time it takes to initialize and run applications can vary widely across languages. As you can see, each language has its own performance characteristics that matter significantly when working on constrained devices.
00:23:25.550
Through experimentation, I’ve found that mRuby has significant hurdles in terms of cross-compiling for my target devices. Some libraries necessary for mRuby may not be available on those devices, making it particularly challenging.
00:24:50.370
I want to emphasize that developers must understand their operating environment well before embedding code. Feel free to ask any questions or seek clarifications.
00:34:20.970
As a closing note, the use of mRuby on constrained devices is certainly possible; it just requires careful consideration of the hardware and the embedded environment to be successful.