コンピュータを楽しもう!!

今、自分が面白くていろいろやってみたことを書き綴りたいと思います。連絡先はtarosa.yでgmail.comです。

Luaとmrubyの書き方の違い (2) 「メソッドの定義」

Luaとmrubyの書き方の違いですが、メソッドの定義について書きたいと思います。

メソッドの定義

Luaの場合、luaL_openlib()やlua_register()を使います。mrubyの場合は、mrb_define_method()を使います。メソッドとして、クラスを持っているものと持っていないものを定義することができます。次に、クラスを持っていないメソッドの定義について説明します。

クラスを持たないメソッドの定義

例えば、viewというスクリプトのメソッドを作成したい場合、
Luaでは以下のように書きます。

lua_register( LuaLinkP, "view", lua_kernel_view );

LuaLinkPは、lua_open()でオープンしたlua_State構造体のポインタです。lua_kernel_viewは、実際の処理を書くCの関数名です。
mrubyでは以下のように書きます。

mrb_define_method(mrb, mrb->kernel_module, "view", mrb_kernel_view, ARGS_REQ(2) | ARGS_OPT(1));

mrbは、mrb_open()でオープンしたmrb_state構造体のポインタです。クラスを持たないメソッドを定義したい場合、mrubyの場合は第2引数に mrb->kernel_module を書きます。mrb_kernel_viewは、実際の処理を書くCの関数名です。
ARGS_REQ(2) | ARGS_OPT(1)と書いているのは、メソッドviewがどのような引数を持つかを設定するところです。Luaの場合は引数がスタックに詰まれて行き、特に制限が無いのですが、mrubyの場合、mrb_define_method()で必須なのか任意なのかを設定しておく必要があります。

クラスを持つメソッドの定義

例えば、Left.viewというスクリプトのメソッドを作成したい場合、
Luaでは以下のように書きます。

static const luaL_Reg RightTbl[] = {
    {"view", lua_kernel_view},
    {NULL,NULL}
};

void foo()
{
    lua_State *LuaLinkP = lua_open();
    luaL_openlibs( LuaLinkP );

    luaL_openlib(LuaLinkP, "Right", RightTbl, 0);
...

Luaでは、クラスとしてまとめたいメソッドについてluaL_Reg 配列をテーブルとして作ります。そして、メソッドの定義として、luaL_openlib()を使い、第2引数にクラス名、第3引数にluaL_Reg配列名を書きます。
Luaの場合、クラス名は大文字で始まる必要も無く、以下のように書いても大丈夫です。

    luaL_openlib(LuaLinkP, "right", RightTbl, 0);

mrubyでは以下のように書きます。

void foo()
{
    mrb_state *mrb = mrb_open();

    struct RClass *RightModule = mrb_define_module(mrb, "Right");

    mrb_define_module_function(mrb, RightModule , "view", mrb_kernel_view, ARGS_REQ(2) | ARGS_OPT(1));
...

mrubyでは、mrb_define_module()を用いてクラスを定義します。そして、メソッドを定義するmrb_define_module_function()の第2引数にRClass構造体のポインタをセットします。それ以降は、メソッドの定義と同じです。
mrubyの場合、クラス名の先頭文字は大文字にする必要があるようです。これはRubyの決まりなのでしょうか?私はRubyの勉強不足なので良く分かっていません。


クラスをメソッドの書き方は、Luaとmrubyとで少し違いますが、慣れればどちらも対して変りません。メソッドの引数の設定を行わなければならない分、mrubyの方が面倒かも知れませんが、実際、メソッド内の処理を書く上でLuaよりは楽なことが分かりました。まっ、どこで楽をするかでしょうね。

LuaはVer5.1.5、mrubyはVer 2013.3.20版を基にしています。