zenspider.com by ryan davis

Description

Inline allows you to write foreign code within your ruby code. It automatically determines if the code in question has changed and builds it only when necessary. The extensions are then automatically loaded into the class/module that defines it.

You can even write extra builders that will allow you to write inlined code in any language. Use Inline::C as a template and look at Module#inline for the required API.

Example

In, 3.x, RubyInline has the ability to do any language, although I don’t support anything but C/C++ out of the box. Here is a basic example of what RubyInline can do:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  class MyTest
  
    def factorial(n)
      f = 1
      n.downto(2) { |x| f *= x }
      f
    end
  
    inline :C do |builder|
      builder.c "
      long factorial_c(int max) {
        int i=max, result=1;
        while (i >= 2) { result *= i--; }
        return result;
      }"
    end
  end

The time for 1 million iterations of factorial and factorial_c is 27 and 7 respectively on my PowerBook (you can run ‘rake bench’ from a RubyInline tarball on your hardware to get numbers for your platform).

RubyInline and RubyToC

I’ve made advances to ruby2c on RubyForge that allow me to write 13 lines of code to create Inline::Ruby. Behold:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  module Inline
    class Ruby < Inline::C
      def initialize(mod)
        super
      end
  
      def optimize(meth)
        src = RubyToC.translate(@mod, meth)
        @mod.class_eval "alias :#{meth}_slow :#{meth}"
        @mod.class_eval "remove_method :#{meth}"
        c src
      end
    end
  end

This allows me to do:

1
2
3
4
5
6
7
8
9
10
11
12
13
  require 'inline'
  class MyTest
  
    def factorial(n)
      f = 1
      n.downto(2) { |x| f *= x }
      f
    end
  
    inline(:Ruby) do |builder|
      builder.optimize :factorial
    end
  end

And it just works.

Rad.