mrubyの小ネタ集

前回の関連で得た知見をそのまま忘れるに任せるのもちょっと惜しいと思ったので、小さく小ネタ集として残しておきます。

ローカル変数は最大約512個

mrubyのバイトコード上レジスタは最大でも512個しかありません。
そしてローカル変数1つにつき1つレジスタが割り振られるため、ローカル変数は最大で512個しか使えません。
さらに、メソッド呼び出しなど各種処理でもレジスタを使うので、前後のコード次第で事実上はもう少し少ない数になります。
足りなくなるということはないでしょうが、そういう仕組みなのだということは覚えておくと役に立つこともあるかもしれません。

リテラルの文字表現は最大1023文字

整数実数文字列といったリテラルを文字で表記するとき、最大文字数は1023文字となります。
文字列の場合は””を含まない本体の文字数、8進数は先頭の0もしくは0_を除いた文字数、16進数も同じく先頭の0xを除いた文字数が1023までなら使用できます。

少し前まではMRB_PARSER_BUF_SIZEという設定をいじれば変更できたのですが、私がしたバグ報告の結果、コンフィグ上から削除され変更は推奨されなくなりました。
一応/include/mruby/compile.hにまだ定義されているので、興味のある人は最大65535の範囲でいじってみましょう。

リテラルは使用した回数だけ定義される

短い文字列は毎回書いてしまうこともありますが、mrubyは11/30現在までのところ同一のリテラルをまとめる機能はありません。
実際同じ文字リテラルを複数使うコードをmrbcしたものをバイナリエディタで覗くと同じ文字列が複数個ならんでいるのが確認できます。

メモリー効率を考えるなら複数回同じリテラルは使わず、一度変数に代入し使いまわすようにするといいようです。

post引数という定義がある

post引数という定義の引数があります。
具体的には

def func(normal, *rest, post)

のpostという引数が相当します。

これは可変長引数の後の通常引数で、解釈は先頭から通常引数、末尾からpost引数と確定させていき、残りを可変長引数と解釈するようです。

mrubyの小ネタとして書きましたが、普通にrubyにもあります。

通常引数・オプション引数・post引数の数は31個まで

通常の引数の数は31個までしか受け取れません。
32個以上受け取るコードを書いた場合、特にシンタックスエラーにはなりませんがバイトコードは壊れます。
同様にオプション引数、post引数も31個しか定義できません。

合計が31個ではなく各引数が31個なので、組み合わせれば90個を超える引数でも可変長引数を使わずに受け取れます。

ローカル変数の名前はコンパイル時に破棄されている

2014/05/17追記:公式でローカル変数情報が実装されました、今ではKernel#local_variablesも動作するようになっています。

rubyであればKernel#local_variablesでローカル変数名の一覧が取得できますが、mrubyの場合コンパイル時にローカル変数名はすべて破棄されています。
ではどう管理されているかというと、変数一つにつきレジスタが一つ割り振られ、レジスタの1番地などという形で扱われます。
ちなみに、当然のことですがグローバル変数やインスタンス変数などはちゃんと変数名はシンボルとして処理されています。

終わりに

いかがだったでしょうか。
主にバイトコード内の定義上の限界から攻めていったので、最大数がどーたらというのが多かった気がします。
一応全部実際にコードを書いて試したつもりですが、何かミスなどあればコメントくだされば直しておきます。

ではまた。