Feb 23, 2009 @ 12:07 am

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.

Bookmark this post : These icons link to social bookmarking sites where readers can share and discover new web pages.
  • DZone
  • Reddit
  • del.icio.us
  • Digg
  • Furl
  • Technorati
  • StumbleUpon
Posted under : In depth
15 Comments

Great post. I’m waiting for the next parts.

Comment by : mcveatNo Gravatar
— February 23, 2009 @ 1:40 pm

Interesting post, I can’t wait for the next one.

Comment by : ScottNo Gravatar
— February 23, 2009 @ 7:35 pm

Very nice explanation Frank! I had lots of trouble explaining this in a simple way, but you did it!

Comment by : macournoyerNo Gravatar
— February 23, 2009 @ 8:25 pm

Thanks guys I’m glad you liked the post! I’ve been working on that kind of stuff recently and I realized that there wasn’t a lot of info on the subject.

Comment by : FrankNo Gravatar
— February 23, 2009 @ 10:29 pm

I learned a lot, thanks!

Comment by : Noam BNo Gravatar
— February 24, 2009 @ 3:04 am

Why not use ffi? or at least mention it.

Comment by : Chris BurkeNo Gravatar
— February 24, 2009 @ 9:14 pm

I don’t know much of this extension. Why don’t you write a post about it instead?

Comment by : FrankNo Gravatar
— February 24, 2009 @ 10:29 pm

In addition to ffi, there’s also Ruby/DL: ttsky.net/ruby/ruby-dl.html

Comment by : Super GooNo Gravatar
— February 25, 2009 @ 5:19 pm

Nice intro, waiting for the second part. Is ffi still experimental or slower than writing a c ext?

Comment by : ActsAsFlinnNo Gravatar
— February 26, 2009 @ 8:39 pm

Great look in depth !

Comment by : simNo Gravatar
— September 15, 2009 @ 12:12 am

Insightful.
Can has part 2 now? plzkthx ;D

Comment by : MikeNo Gravatar
— December 16, 2009 @ 7:07 am

FFI is definitely the way to go for adapting a library.

Comment by : Jason WatkinsNo Gravatar
— January 5, 2010 @ 2:25 am

Mike, haha :) Never again will I put “Part 1″ in a post title…

I really intended to follow through with the second part but I never had the time. I swear one day it will come out… and hopefully people will still find it useful.

Comment by : FrankNo Gravatar
— January 14, 2010 @ 4:33 pm

Pointer…

Your topic Ruby Fleebie ” Ruby and C : Part 1 was useful….

Comment by : Pointer
— February 1, 2010 @ 10:35 am

Give us more :)

Comment by : ApneadivingNo Gravatar
— September 20, 2010 @ 4:43 pm




Leave a comment
Name (required)
Email (will not be publish) (required)
Website