DEV Community

Tomoyuki Sahara
Tomoyuki Sahara

Posted on

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

注: この記事は 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_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]

Top comments (0)

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More