Help us understand the problem. What is going on with this article?

1.0.0 でも master でも動く mrbgem の書き方

More than 5 years have passed since last update.

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_valuestruct 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]

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away