ホーム‎ > ‎Ruby入門‎ > ‎

Ruby 発展編

更なるRubyの深みにハマりたい方々のためにRubyの発展編を用意致しました。

拡張ライブラリの作成
※この節ではC言語の最低限の知識を前提としているので、C言語がわからない方は飛ばしていただいても構いません。

今まで見てきていただければわかる通り、Rubyは大変手軽な文法と強力なライブラリを兼ね備えた言語です。しかし、Rubyはスクリプト言語なのでヘビーな計算には耐えられません。そこで、計算部分をC言語で書かれた拡張ライブラリに押し付けて大枠をRubyで仕上げるという策を取ります。本節では、C言語の基本的な部分を知っている方を対象に、Ruby拡張ライブラリの作成方法を紹介します。
例としてある整数が素数かどうか判定するメソッドprime?の定義されたモジュールPrimeを作成してみます。まずは、C言語のソースコードであるprime.cを作成します。Ruby拡張ライブラリ作成のためには、ヘッダファイルとしてruby.hを読み込む必要があります。
#include <ruby.h>
次に、元となる関数を用意しましょう。
int prime(int n){
    int i;
    if(n <= 1){
        return 1;
    }
    for(i = 2;i < (n/2+1);i++){
        if(n % i == 0){
            return 1;
        }
    }
    return 0;
}
これは、引数が素数なら0を、素数でなければ1を返す関数です。これを元にRubyの関数を作成しましょう。
VALUE prime2(VALUE self, VALUE n){
    VALUE boo;
    int m = NUM2INT(n); /* Rubyの整数値をC言語のintに変換する。 */
    m = prime(m);       /* 素数かどうかの判定。 */
    if(m == 0){
        boo = INT2NUM(0); /* C言語の整数0をRubyの整数1に直す。 */
    }else{
        boo = INT2NUM(1);
    }
    return rb_equal(boo,INT2NUM(0)); /* boo == 0 */
}
ここで見慣れない変数型VALUEが登場しています。これはRubyの値一般を表す構造体で、Rubyの値は整数・浮動小数点・文字列・bool値・その他いかなるオブジェクトも全てVALUEとしてひとまとめにされます。最後に、モジュールPrimeを作成してprime2prime?として登録しましょう。
void Init_Prime(void){ /* 関数名はInit_(モジュール名) */
    VALUE rb_mPrime; /* この変数名は特にこだわる必要はない。 */
    rb_mPrime = rb_define_module("Prime"); /* モジュールPrimeを生成してrb_mPrimeに代入。 */
    rb_define_module_function(rb_mPrime,"prime?",prime2,1); /* メソッドを登録。 */
}
これでライブラリのソースコードが完成しました。次にコンパイル作業に入ります。これはC言語で書かれたソースなのですが、gccで普通にコンパイルしても動きません。Rubyにはmkmfという拡張パッケージを作るためのパッケージが存在するのでこれを用います。まず、extconf.rbというファイルを作成して、次の2行を打ち込みます。
require "mkmf"
create_makefile("Prime")
そして、端末で次の命令を実行します。
$ ruby extconf.rb
$ make
これで拡張ライブラリPrime.soが作成されました。エラーが出る場合にはこちらをご覧ください。早速、irbでテストしてみましょう。
> require "./Prime.so"
true
> Prime.prime?(5)
true
> Prime.prime?(4)
false
拡張ライブラリ作成のためのC言語の命令はリファレンスマニュアルのC APIの項にまとめられています。
リファレンスマニュアル 関数一覧: http://doc.ruby-lang.org/ja/2.3.0/function/index.html

Comments