注: この記事は 2014/03 に書いたものです。
mruby の安定版1.0.0と最新版のどちらでも動作する mrbgem の書き方を紹介します。以下では、安定版のことを 1.0.0、最新版のことを master と呼びます。
C 言語 API の変更
mrb_str_cat_lit の追加
mrb_str_cat_lit
の動作は mrb_str_cat_cstr
と同じです。strlen(3) 一回分速いだけの違いしかありませんから、mrb_str_cat_cstr
を使っておけば間違いありません。
mrb_const_defined_at の引数の型の変更
返り値と第二引数の型が異なります。第二引数の型は mrb_value
と struct RClass *
でまったく異なるため注意が必要です。
/* master */ mrb_bool mrb_const_defined_at(mrb_state *mrb, mrb_value mod, mrb_sym id);
/* 1.0.0 */ int mrb_const_defined_at(mrb_state *mrb, struct RClass *klass, mrb_sym id);
mrb_class_get の仕様変更
mrb_module_get
は 1.0.0 と master の違いの中でもっともひっかかりやすいものです。1.0.0 では mrb_class_get
の引数としてクラスもモジュールもどちらも指定できましたが、master ではクラスしか指定できなくなりました。モジュールを得るためには替わりに mrb_module_get
を使う必要があります。重要な非互換ですが、対応は容易です。1.0.0 では mrb_module_get
は以下のように定義できます。
#if MRUBY_RELEASE_NO < 10000
static struct RClass *
mrb_module_get(mrb_state *mrb, const char *name)
{
return mrb_class_get(mrb, name);
}
#endif
例: https://github.com/iij/mruby-io/blob/master/src/io.c#L23
mrb_yield_internal の名称変更
mrb_yield_internal
は 1.0.0 では非公開な API という位置付けでしたが、便利なためいくつかの mrbgem から利用されていました。master では mrb_yield_with_class
と名前を変え、mruby.h で公開されるようになりました。
Ruby 言語処理系としての動作の変更
const_defined? の変更
トップレベルで定義されているモジュール/クラスの名前を Module#const_defined? に与えると、master では true が返ってきます。これは CRuby と同じ挙動です。1.0.0 では false を返してきました。
class A
end
class B
end
p B.const_defined? :A
p B.const_get :A
% mruby a.rb
true
A
% mruby-1.0.0 a.rb
false
A
Float#nan? の追加
Float#nan? は master にはありますが 1.0.0 にはありません。以下のように実装できます。
unless Float.method_defined? :nan?
class Float
def nan?
not (self == self)
end
end
end
例: https://github.com/iij/mruby-iijson/blob/master/mrblib/json.rb#L104
Integer#div の追加
Integer#div は master にはありますが 1.0.0 にはありません。以下のように実装できます。あるいは、1.0.0 にもある Integer#divmod
を使って回避することも可能です。
unless Integer.method_defined? :div
class Integer
def div(other)
self.divmod(other)[0]
end
end
end
または 123.div(45)
=> 123.divmod(45)[0]
Top comments (0)