Ruby and C : Part 1

This first part aims at explaining how Ruby in the background is not Ruby anymore. In the next part I’m going to talk about HOW to bridge some existing C library with your ruby application.

As you might know already, the official ruby interpreter is written in pure C. This means that whenever you type a ruby instruction, the interpreter will call the corresponding C function for you. For example, if you do :

arr = Array.new

Ruby will call a C function (probably rb_ary_new) and a C structure will be created to hold the content of arr. When you will try to access arr later in your code, the interpreter will use that same C structure.

On the ruby side of things we say that everything is an object. On the C side of things we say that everything is a VALUE

You also already know that everything in ruby is an object. To represent this reality on the C side of things, a custom type (typedef) has been created and has been given the name of VALUE. This type is a pointer (well, in fact it is not really a pointer but we won’t go into this right now) that can reference any kind of data type. When C defines something as a VALUE, you know that it is dealing with something that either A) comes from the ruby side of things, B) will be returned to the ruby side of things or C) is usable on the ruby side of things in one way or another. In all other situations, C is just C and doesn’t need the VALUE data type. When you see C using VALUE, what you are really seeing is ruby from the inside, and ruby from the inside is an ugly beast. It is not pretty, not elegant, not easy, not cool and honestly not that interesting. The thing is, it can save you a lot of work if you want to bridge an existing C library into your ruby application instead of having to rewrite the whole thing in plain ruby. That, in part, is why it can be very useful to know a little bit of ruby’s ugly side.

Let’s move on. We said that VALUE was the C way to represent a ruby object. If you open one of the source file of the ruby interpreter (array.c, string.c, etc.), you will find that the word VALUE is used everywhere :

VALUE rb_do_stuff(VALUE param1, VALUE param2) {
  VALUE some_variable;
  int x;
  //bla bla bla bla
  return some_variable;
}

Since everything in ruby is an object (or a VALUE), the C functions that are responsible of returning something ready to use on the ruby side of things always have to return a VALUE. If they would return something else (int, char, char *, long), ruby would complain because it can understand objects and only objects.

A Fixnum is not a int, it is a VALUE. A Bignum is not a long, it is a VALUE. A String is not a char *, it is a VALUE, and so on.

VALUE is not really a pointer, you say?

Ok the following is not really important for the sake of this post but if you’re curious it will interest you. I said earlier that VALUE wasn’t really a pointer. Time has come to explain what it is and why. VALUE is in fact an unsigned long.
There is only one reason why VALUE is an unsigned long and not a pointer : efficiency.
Remember what a pointer is? It is a variable that contains an address to some structure in memory. It is perfect for complex objects like arrays, hashes and custom objects… but it is a bit overkill for more primitive objects like Fixnums, booleans (TrueClass and FalseClass instances) and nil (NilClass instance). Ruby inventor thought that it would be great if in some cases the VALUE object could BE the data instead of POINTING TO the data. I mean, why having a VALUE that points to a structure that contains an integer that contains the number 1 when you could simply have a VALUE that contains the number 1?
So instead of being a pointer, VALUE is an unsigned long that can contain either A) an address to some structure that contains the data or B) the data itself (immediate value).
The data in a VALUE is stored in such a way that it is possible to know if it contains an address to some structure in memory or an immediate value. Ingenious, ain’t it?
In my next post, I will try to explain how you can use the ugly side of ruby to bridge an existing C library into your ruby (or rubyonrails) application.

Geany IN, Komodo OUT

First of all, I’d like to deny the rumor that I am dead.
I’m struggling since day #1 to find a good code editor for ruby. Mac users are happy with their textmate… but what’s left for us linux users? I tried gedit, vim, scribes and eclipse (with the aptana plugin) but wasn’t happy enough with any of them. I thought I found a real gem in Komodo edit, but that’s just not doing it for me anymore. Komodo is a great editor but it is plagued with a huge problem : it is slow and unresponsive. Sometime you start typing code and you won’t see what you just typed on the screen. Wait a few seconds and boom, here is your code… full of typos.
Now that my honey moon with Komodo is over, I searched the web and found Geany, a light-weight code editor that works for linux and windows. I’m very satisfied with it so far. Instead of making a half-assed review of the editor, I think you should try it by yourself and decide if you like it or not.
Off topic note :
Those who liked the “in depth” posts I was doing in the early days of this blog might be disappointed with the kind of posts I’m doing now. I’m thinking about this for some time and I can say that I am planning to start writing like those early days. Why? Well, simply because I found it more enjoyable. The problem however is finding the time to write longer and more in-depth posts. I am currently quite busy with TimmyOnTime and other projects so unfortunately RubyFleebie is suffering from it. I want to thank you for your patience… it amazes me that I still have all those subscribers and daily readers.