組み込みC言語プログラマのためのmruby入門(前編) ―― Rubyとmruby,何が違う? どう違う?
●1Mバイト程度のRAMが必要
mrubyは,言語として成立するための必要最低限の機能しか提供しません.最低限求められるOSの機能とは,動的なメモリ確保のみです.動的メモリ確保の手段も,標準ライブラリに含まれるmalloc以外のものと差し替えることが可能です.標準入出力や時刻取得といった機能は,コンパイル時に切り離すことができるようになっています.この性質は,Rubyとは対照的です.Rubyは,OSに存在する機能はすべて提供しているのではないかと思えるほど,豊富なライブラリがそろっています.
最低限の機能を提供するという方針は,主となるアプリケーションの邪魔をしないというメリットになります.また,μITRONのような独自のAPI(Application Programming Interface)を提供している環境や,OSが存在しない環境への移植が行いやすいというメリットにもなります.
サブセットになっているとはいえ,mrubyは,メモリ容量として1Mバイト程度のRAMが(現時点では)必要になります.なお,現時点でも,パラメータ・チューニングでRAMを640Kバイト程度まで追い込むことはできます.無理をすれば128KバイトのRAMでの動作実績もありますが,言語としての自由度や処理速度などを犠牲にしており,その成果が汎用的に使われることはないと思われます.将来的には,384Kバイト~512Kバイト程度のRAMと,同程度のROMが最低限の要求となる実装に落ち着く,と想定しておくのが無難な線と思われます.
●プリコンパイルしてから実行
mruby以外のRuby処理系は,スクリプト言語であることを意識したものになっています注3.これに対してmrubyは,(後ほど紹介するように)対話型の環境やスクリプトの直接実行も可能ではありますが,基本的には事前にバイトコード(中間コード)にコンパイル(プリコンパイル)してから実行します.Javaと同じような手順を想像していただくと近いかもしれません.
注3:Ruby 1.9からは,内部的にはバイトコードにコンパイルしてVM(Virtual Machine)で実行しているし,バイトコードを読み込ませて実行することもできるが,一般的には用いられていない.
スクリプトの構文解釈は,メモリを大量に消費します.プリコンパイルを行うことで,実行時に必要なRAM占有量を大幅に削減できます.なお,バイトコード・コンパイラの結果出力は,バイナリ・コードに加えて,C言語の配列の形式(つまりソース・コード)も可能となっています.mrubyのコアとソース・コード形式のバイトコードをリンクすれば,既存のアプリケーションにmrubyで記述された機能を簡単に追加できます.
ちなみに,上記のソース・コード形式での出力を応用して,mrubyのコアは,それ自身の一部がC言語ではなくRubyで記述されています.
●文法の違いは無視できるくらい小さい
mrubyとその他のRuby処理系は言語仕様的にみるとおおむね互換ですが,mrubyにはヒア・ドキュメント注4が無く,現時点では正規表現を有効にできないなど,いくつかサブセットになっている個所があります.これらが将来的に実装されるのか否かは,明確にはなっていません.もし正規表現が実装されても,コンパイル時に切り離せるようになるものと思われます.ファイルや標準出力がコアから切り離せるmrubyでは,ヒア・ドキュメントがあっても生成の先がないかもしれません.また,事前にバイト・コード・コンパイルすることを考えると,さまざまな検討事項がありそうです.このような違いはありますが,mrubyとRubyの間の文法の差異は,おおむね無視できるくらいに小さなものです.
注4:ヒア・ドキュメント(Here Document)とは,スクリプト・ファイル中にまとまった文章を記述・利用する機能である.
●ライブラリはRubyのサブセット
ライブラリについては,mrubyはRubyの大幅なサブセットになっています.基本的なクラスについても手が入っています.Rubyには,けた数制限のない整数演算がありますが,mrubyには,C言語のint型と等しい整数型しかありません.浮動小数点型も,C言語のdoubleかfloatかをコンパイル時に選ぶようになっています.ファイル入出力のためのライブラリも削られています.
本稿執筆時点でのmrubyのコア・ライブラリを,表1に示します.
表1 mrubyのコア・ライブラリ(2012年10月時点)
種別 | シンボル名 |
クラス | Object, Module, Class, NilClass, TrueClass, FalseClass, Numeric, Integer, Fixnum, Float, String, Symbol, Array, Hash, Range, Regexp (*1), MatchData (*1), Proc, Struct, Time (*2) |
モジュール | Kernel, Enumerable, Comparable, GC, Math |
例外クラス | Exception, StandardError, ArgumentError, LocalJumpError, RangeError, FloatDomainError, RegExpError, TypeError, NameError, NoMethodError, IndexError, KeyError, NotImplementedError |
(*1):オプション.本稿執筆時点では未実装.
(*2):オプション.
またmrubyのライブラリには,ライブラリとしてはRubyと同じでも,ISO/IEC 30170として承認されたRuby(以下,ISO Ruby)の言語仕様とは挙動が変わっているものがあります.例えば,浮動小数点数をゼロ除算したとき,ISO Rubyでは例外が発生する一方で,mrubyではinf値が返ります.このような変更は,文書化が追いついておらず,mrubyのソース・コードを読みながら理解していく必要があるというのが現状です.