IronRuby Pre Alpha 1 で WPF を試すの巻☆その1

IronRuby を試してみて、まだ Ruby としては事実上使い物にならないけどパフォーマンスは期待しといてよさそう、というのが前回。
今回は IronRuby から WPF ( Windows Presentation Foundation、旧称 Avalon ) をびしばし叩いてみたい。
といっても、簡単なウィンドウを作ってボタンを配置してイベントハンドラ書いて……というレベルのものはすでに作られている方がいるので、IronPythonチュートリアルにある電卓(このビデオの 6:15 頃以降。IronPython1.1 のチュートリアルより古いけど)を IronRuby で実現してみる、というのに挑戦だ。


んが、結論から言うとまだうまく行ってない。いくつもの壁がそびえていて、残念ながらまだゴールにたどり着けていない。


チュートリアルでは XAML を読み込んで Window.Content に設定している。
というわけでまずは FileStream を作りたい。

IronRuby で FileStream への参照を有効にするには mscorlib を require する。

require 'mscorlib'

これで System::IO::FileStream クラスを参照できるようになるが、そのコンストラクタに与えるべき FileMode.Open の値が取れない。
FileMode は列挙体で、おそらく Ruby の Enumerable にマッピングされていると思われる(少なくとも JRuby はそうだった)。が、IronRuby はその Enumerable が未実装なのだ……

というわけで、通常の FileStream コンストラクタを使わずにインスタンスを生成し、XamlReader.Load に与えると悲しいエラーが出る。

require 'PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
require 'PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'

f = System::IO::File.open_read('Calc.xaml')
element = System::Windows::Markup::XamlReader.load(f)
Ruby.Builtins.LoadError: ファイルまたはアセンブリ 'System.IO.FileStream'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。
---> System.IO.FileNotFoundException: ファイルまたはアセンブリ 'System.IO.FileStream'、またはその依存関係の 1 つが読み込めませんでした。指定されたファイルが見つかりません。
ファイル名 'System.IO.FileStream' です。

アセンブリの解決に行っているのだろうと思うのだが、明らかに探し方が間違っているっぽい……
というわけで XAML の読み込みは見込みがなさそうなので、XAML を使わずせっせと手組みしてみている。 <いまここ


この他にも困難は多々あり、

  • Module.include が未実装なので、WPF の定数・クラス・構造体・その他全てをフルネームで書くか、手で定数定義する必要がある
  • リフレクション系が未実装なので、どんなメソッドがあるのか等わからない。元の WPF のメソッドは「先頭の大文字→小文字、途中の大文字→_小文字」*1というルールで変換されてマッピングされているので .NET Framework のリファレンスを見れば基本わかるのだが、マッピング先がわかりにくい場合もあるし、MSDN ライブラリは遅いし、やっぱり対話型であればリフレクションは欲しい
  • Thread.new と join は一応実装されているっぽい(ブロックを {} で書いたら駄目。do〜end で書く必要がある)のだが、WPF のメッセージループ呼び出しを Thread に書くとエラーで落ちる。つまり対話型でウィンドウをいじれない orz

とまあ絵に描いたような茨の道。
ここまでたどり着くだけでも、ずいぶん中島さんに助けてもらってしまった(感謝)。
Ruby は一通り知ってて、IronRuby に興味はあるけど、.NET のことは深く知らない」という人はせめて Pre が取れるまで手を出さない方が良さそう。


そんなこんなで、IronRuby で電卓を作るのにもう少しかかりそうなのだが、こうして触っているうちに WPF がちょっと楽しくなってしまって、IronPython に浮気中。
こっちは少し頑張れば結構おもしろいものができそう〜。

*1:後者はなくてもいいっぽい