polishing ruby by ryan davis

Writing C Extensions, Improved

Published 2006-08-01 @ 13:31

Tagged rubyinline, ruby

I recently read How to create a Ruby extension in C in under 5 minutes by Peter Cooper. I decided to replicate the example to see how things fare these days. I basically followed his lead, typing in everything, but cleaning up the code to suit my tastes a bit better (and in some cases, to be more correct in C-land).

First, I wrote the following:

#!/usr/local/bin/ruby -w

require 'mkmf'
extension_name = 'example'
dir_config(extension_name)
create_makefile(extension_name)

Nothing fancy, just a simple mkmf generator. I don’t like mkmf (esp. its insides), but this is clean enough. After that, I wrote (and cleaned up) the C file:

#include "ruby.h"

static VALUE method_test1(VALUE self) {
  int x = 10;
  return INT2NUM(x);
}

void Init_example() {
  VALUE Example = rb_define_module("Example");
  rb_define_method(Example, "test1", method_test1, 0);
}

Nothing fancy. The only real differences from the original were made to keep the symbol table clean. All in all, it took me about 7 minutes, not too far off from the original article’s title. And sure enough, it can be run just fine via:

./example-build.rb
make
ruby -I. -rexample -e 'include Example; puts test1'

Not too bad. I don’t have any real complaints about that… except that the alternative is so much easier and so much cleaner that I don’t really see why anyone would choose this way of going about it. Examine:

#!/usr/local/bin/ruby -w

require 'rubygems'
require 'inline'

class Example
  inline(:C) do |builder|
    builder.c "int test1() {
                 int x = 10;
                 return x;
               }"
  end
end

p Example.new.test1

and you run it with:

./example.rb

Notice how I just run the script? That is because compiling, linking, and loading are all handled for you, as needed, and you can never accidentally skip a step. Notice how I just write plain C? int test1() is about as clean as you can get. Notice how I return x straight up? No type conversions here.

The point is to remove the distractions so you can get your work done. No more wondering “did I type make?” or “what is the proper macro to convert a string?” as it is all handled for you. Give developers the tools they need so they can stay in thought, not in process.

It doesn’t get simpler than this… and really, it shouldn’t ever be more difficult than this.