BundlerでC拡張を含んだgemを作ってテストする
fukayatsuが来年学ぶべき言語は『C』です。 http://t.co/pFf1wzHZ5r
— ふかやつ (@fukayatsu) December 31, 2013
ということなのでC拡張を含むgemを初めて作ったのがこちら。
#include <stdio.h> #include <ruby.h> static VALUE c_hello(VALUE self, VALUE name_val) { char *name = StringValuePtr(name_val); char greet[100]; sprintf(greet, "Hello, %s", name); return rb_str_new2(greet); } void Init_hello_gem_with_extensions(void) { VALUE cHelloGemWithExtensions; cHelloGemWithExtensions = rb_const_get(rb_cObject, rb_intern("HelloGemWithExtensions")); rb_define_method(cHelloGemWithExtensions, "hello", c_hello, 1); }
C言語側でRubyのHelloGemWithExtensionsクラスにhelloという名前で引数を一つ取るc_helloメソッドを登録している。
require 'spec_helper' describe HelloGemWithExtensions do subject { HelloGemWithExtensions.new } it { expect(subject.hello('C extension')).to eq "Hello, C extension" } end
それをRubyから呼ぶテスト。簡単ですごい。
雑感
- 『Rubyソースコード完全解説』を昨日ちょっと読んでたので、「VALUEってなんだよ」とか思わずに済んだ。
- bundle gem fooとした時に拡張ライブラリ用のディレクトリやファイルを作成するオプションがあると便利そう
- luislavena/rake-compiler便利。
spec.add_development_dependency "rake-compiler"
しておく
- compile時に生成されるファイルをgitignoreしておく。
- jrubyとrubiniusでテストが失敗するけど保留している
- jrubyの場合はC拡張を読み込むために、"JRUBY_OPTS=-Xcext.enabled=true"が必要らしい
参考にしたリンク
Ruby - BundlerでC拡張を含んだgemを公開する - Qiita [キータ]
http://qiita.com/gam0022/items/2ee82e84e5c9f608eb85
Gems with Extensions - RubyGems Guides
http://guides.rubygems.org/gems-with-extensions/
Ruby用拡張ライブラリをCで作る --- Little Penguin
http://members.jcom.home.ne.jp/mitakelp/old/_hellorb.html
Rubyの拡張ライブラリを作ってみよう! - ser1zw's blog
http://ser1zw.hatenablog.com/entry/20111217/1324133118
『Rubyソースコード完全解説』サポートページ
http://i.loveruby.net/ja/rhg/