2018/03/21(水) [n年前の日記]
#1 [ruby][mruby] Rubyにおいてnew以外でクラスを生成する書き方
DXRuby の Image のように、Image.new でもクラス(のインスタンス)を生成できるけど Image.load("画像ファイル名") でも生成できる、そんなクラスを作りたかったのだけど、その方法がずっと分からなかったわけで。
しかし、 _dxruby_sdl や _dxsdl2r の image.rb を眺めて、「あっ…そうやればいいのか」と分かった、とメモ。
_dxruby_sdl/image.rb at master - takaokouji/dxruby_sdl
_dxsdl2r/image.rb at master - mirichi/dxsdl2r
つまり、クラスの中で、def self.load 〜 end でクラスメソッドを作って、その中で自身のクラス、のインスタンスを .new で生成して、その生成したインスタンスを返してやればいいのだなと。
であれば、それを mruby を組み込んだCのプログラムの中でやればいい…。
mruby でクラスメソッドを定義するのは、 _mrb_define_class_method() 。ちなみに、インスタンスメソッドを定義するのは、 _mrb_define_method 。なので、以下のような感じの記述になるはず。
メソッドに対応する関数の中で、インスタンスを生成するのは、 _mrb_obj_new() 。
そんな感じで、以下のようなソースになった。…ちょっと長くなりすぎてしまったので、github に置いておきました。
_mieki256/glmrubysdl2-c
_glmrubysdl2-c/glmrubysdl2.c
しかし、 _dxruby_sdl や _dxsdl2r の image.rb を眺めて、「あっ…そうやればいいのか」と分かった、とメモ。
_dxruby_sdl/image.rb at master - takaokouji/dxruby_sdl
_dxsdl2r/image.rb at master - mirichi/dxsdl2r
つまり、クラスの中で、def self.load 〜 end でクラスメソッドを作って、その中で自身のクラス、のインスタンスを .new で生成して、その生成したインスタンスを返してやればいいのだなと。
であれば、それを mruby を組み込んだCのプログラムの中でやればいい…。
mruby でクラスメソッドを定義するのは、 _mrb_define_class_method() 。ちなみに、インスタンスメソッドを定義するのは、 _mrb_define_method 。なので、以下のような感じの記述になるはず。
// define class cImage = mrb_define_class(mrb, "ImageSurface", mrb->object_class); MRB_SET_INSTANCE_TT(cImage, MRB_TT_DATA); // define class method mrb_define_class_method(mrb, cImage, "load", glmrb_image_load, MRB_ARGS_REQ(1)); // define instance method mrb_define_method(mrb, cImage, "initialize", glmrb_image_initialize, MRB_ARGS_REQ(3));
メソッドに対応する関数の中で、インスタンスを生成するのは、 _mrb_obj_new() 。
mrb_value param[3]; param[0] = mrb_nil_value(); param[1] = mrb_nil_value(); param[2] = mrb_ary_new(mrb); mrb_value obj = mrb_obj_new(mrb, cImage, 3, param); ... return obj;
そんな感じで、以下のようなソースになった。…ちょっと長くなりすぎてしまったので、github に置いておきました。
_mieki256/glmrubysdl2-c
_glmrubysdl2-c/glmrubysdl2.c
[ ツッコむ ]
以上です。