実務指向のJRuby
ささだ氏のセッションに続いて、サンマイクロシステムズのCharls Nutter氏によるJRubyのセッションが行われた。
JRubyはYARVを組み込むことで高速化へのスタート地点に立ったMRI(まつもと氏が開発した最初のRubyをMatz Ruby ImplementationのアクロニムでMRIと呼んで他のRuby実装と区別する)と異なり、すでに高速化をきわめつつあるJVM上に実装しているという特徴がある。
たとえば、MRIではスタックを保存することで実現している(そのためパフォーマンスに悪影響がある)ブロックに対する処理は一般に低速である。それに対してJRubyではブロックの中でのbreakのパフォーマンスを大きく向上させている。
この理由としてNutter氏は、JVMフレンドリな実装がキーであると答えている。具体的にはJVMは最適化によって本来低速である例外処理(スタックのたどり直しを行うため一般に低速にならざるを得ない)をジャンプに変換する仕組みを備えている。JRubyはこういったJVMが備えている高速化手法を有効化できるように開発されているのである。
JRubyのもう一つの特徴は、Javaが備えるWORA特性(Write Once、Run Anywhereで、それなりの限界はあるものの、単純なアプリケーションであれば、ほぼそのまま複数の環境で稼働できること)や、JEEに組み込まれたデプロイのためのインフラが利用できることに由来する、配備の簡単さである。
Nutter氏は、warblerという、Railsアプリケーションのwarファイルを作成し(warは、Web Application Archiveファイル)WebコンテナのGlassFishに簡単にデプロイするデモを紹介した。これは、開発したアプリケーションの展開やWebサーバーとの接続戦略にそれなりに頭を悩ませる必要があるMRIのRailsと比較した場合、画期的なソリューションと言える。
その他に以下のようなプロダクトを紹介した。
- NetBeans
- monkeybars
- Ruby-Processing
このようにNutter氏のセッションからは、現時点で実際に利用可能なプログラミング言語としてのRubyを強調したものを感じることができた。
また、後発の強みを生かして、起動オプションでRuby 1.8とRuby 1.9の切り替えを行うデモを示して(これは実験レベルである)、JRubyの1.9サポートの方向性を示した。
魔法のRubinius(ルビニウス)
実用指向が強いNutter氏のセッションに対して、Evan Phoenix氏によるRubiniusのセッションはRubiniusが目指す方向とは別に、言語ハックの方向に寄った興味深いものだった。
Rubiniusは、YARV同様に新しく開発したVMを利用したRuby実装であるが、コアライブラリを含むカーネルそのものも作り直している。このため、YARV(Ruby 1.9)と異なり既存資産のサポートがそれほどの負荷とならないという特徴がある。具体的には、Rubyを拡張する手法として、Rubyが提供するAPIに従ってCかC++で記述した拡張ライブラリの扱いがYARVと異なり足かせにならないという点だ。
MRI、JRuby、Rubiniusのそれぞれの拡張ライブラリに対する姿勢はまったく異なる。
MRIの場合、既存の拡張ライブラリをサポートするために、既存のAPIをそのまま生かす方法を採用している。
JRubyはJVM上の処理系なので、既存の拡張ライブラリはすべて切り捨てることで対応している。
それに対してRubiniusは、独自の実装と拡張ライブラリを仲介する薄いAPI層を用意することで対応する。これによりJRubyと異なり既存資産が有効に活かせると同時に、MRIと異なり既存APIによって古い実装の維持に対して神経質にならなくても済むというメリットを得ている。
RubiniusのVMの特徴を示すリストをPhoenix氏のプレゼン資料から以下に引用する。
class Rubinius < Smalltalk # form(外見) include Ruby::Syntax # function(機能) include Ruby::Behavior # elbow grease(きつい仕事だけど) include Google.search("crazy cs papers") # すげぇコンピュータサイエンスの論文をググってくる end
これは魅力的だ。その手のプログラミングが好きな開発者であれば思わずぐぐっと来るところである。また、RubiniusではほとんどすべてのVMデータはRubyのクラスとして実装されているため、Rubyでeval(評価器)の実装が十分に可能だとしている。
さらに、Phenix氏のプレゼン資料は、上に引用したように、ほとんどすべてがプログラム(疑似コードを含む)として記述されているため、非常に明確で理解しやすい。たとえば、次のリストは、Rubiniusで"1 + 1"
という文字列をパースしてS式を生成できることを示している。
"1 + 1".to_sexp
=>
[:call, [:lit, 1], :+, [:array, [:lit, 1]]
なお、上記と同様なことはMRIでも可能で、具体的にはNODE* rb_complie_cstr(const char*, const char*, int, int)
APIを呼び出すことで抽象構文木を生成して取り出せる。ただし、MRIの場合はこういった処理を実装するにはCによる記述が不可欠となる。