始めよう!Silverlight

第6回 Dynamic SilverlightでHello world

この記事を読むのに必要な時間:およそ 4 分

IronPythonでもHello world

前回からHello world続きですが,懲りずにIronPythonでもHello worldを表示してみます。

index.htmlとapp.xamlは上記のIronRubyのものをそのまま使用してください。また,実行までの手順もIronRubyの場合と同様です。違いはapp.rbがapp.pyに変わるだけです。以下の内容をapp.pyとして保存してください。

app.py

from System.Windows import Application
from System.Windows.Controls import UserControl

def OnClick(sender, args):
  sender.Text = "Hello world for IronPython!"

control = Application.Current.LoadRootVisual(UserControl(), "app.xaml")
control.TextBlock1.MouseLeftButtonDown += OnClick

では,Chironを /b のオプションを付けて起動してください。このとき,理由は後述しますが,app.rbはappディレクトリに無いようにしておいてください。

index.htmlのリンクを開いて,⁠Hello world」をクリックして,最終的に以下の画面が表示されたら成功です。

画像

IronRubyをもう少し簡単(?)

すこし,話がそれてしまいますがIronRubyがfindNameメソッドを用いてxamlのエレメントを取得していたのに対して,IronPytonで記述した場合は,名前をそのままプロパティのように指定して取得できました。こちらのほうがコードもシンプルで読みやすくなるので,IronRubyでも同様の操作が行えるように少し工夫してみます。

Rubyではmethod_missingという特殊なメソッドが定義されています。このメソッドは,呼び出したメソッドが定義されていなかった場合に呼び出されるメソッドになります。例えばcontrol.TextBlock1とした場合に,TextBlcok1メソッドは定義されていないのでmethod_missingが呼ばれます。そこで,通常の場合は例外が発行されます。このmethod_missingをオーバーライドして,引数に失敗したメソッド名が渡されるので,このメソッド名でfindNameした結果を返すようにします。

class FrameworkElement
  def method_missing(m)
    find_name(m.to_s.to_clr_string)
  end
end

FrameworkElementクラスでmethod_missingをオーバーライドしています。全体のコードは以下のようになります。

Include System::Windows
Include System::Windows::Controls

class FrameworkElement
  def method_missing(m)
    find_name(m.to_s.to_clr_string)
  end
end

control = Application.current.load_root_visual UserControl.new, 'app.xaml'
control.TextBlock1.mouse_left_button_up do |sender,args|
  sender.text = 'Hello world for IronRuby!'
end

アプリケーションが実行されるまで

さて,これでIronRubyでもIronPythonでも無事にHello worldを表示できて,動作させることができました。しかし,一点引っかかる部分がありませんか? おこなった手順としては以下です。

  1. index.htmlを作成
  2. app.xamlを作成
  3. app.rbもしくはapp.pyを作成
  4. Chiron.exe /b で実行

これらの手順のなかのどこにもxapファイルを作成する手順がありません。しかし,問題なく動作しています。しかもindex.htmlでapp.xapを指定しているにもかかわらずです。

実はChiron.exeを/bオプションのみで起動した場合,app.xapファイルは実ファイルとしてではなく,メモリ上で動的に作成して,クライアントにダウンロードしてるのです。またAppManifest.xamlも動的に作成しています。/bオプションのみの場合は,以下のように動作します。

  1. 読み込むxapファイルの拡張子を除いたファイル名のディレクトリを検索(今回の例ではapp)
  2. 1.のディレクトリの中のファイルの拡張子から判断して,含めるDLRのアセンブリを決定し,AppManifest.xamlを生成
  3. 1.のディレクトリと2.のAppManifest.xamlをxapファイルにパッケージング

上記で作成された,xapファイルがクライアントにダウンロードされて実行されることになります。

では,アプリケーションがどのスクリプトファイルから実行されるかはどう判断されているのでしょうか? スクリプトファイルが複数含まれる可能性もあるため,必ず判断が必要になります。

これは,DSLが判断しています。DSLは読み込んだxapファイルを展開して含まれるコードファイルの中からapp.拡張子のファイルを検索します。そして,見つかったファイルを最初に実行します。このときに複数の言語でおなじappというファイル名にしている場合に,DSLは例外を発生させます。これがIronPythonでHello worldを表示するときにapp.rbが無いようにしてくださいと書いた理由です。

このappという値を変更するにはSilverlightプラグインを生成するとのinitParamsにstartというキーで値を指定します。たとえば「test」という値に変更したい場合は以下のように指定します。

<param name="initParams" value="start=test" />

これらの内容はすべてソースコードから読み取ることができます。たしかにソースコードを読み込むことはなかなか大変なことですが,是非一度読んでみることをお勧めします。面白い事実を発見できるかもしれません。例えば,Chiron.exeに対してuriに/bye!を指定するとChiron.exeが終了するとか。

http://localhost:2060/bye!

次回予告

記事としては本当に簡単なコードしか書いていませんが,基本的にDSLだからSilverlightのどれそれの機能は使えないということはありません。DSLでも自由に開発が可能です。また,今回紹介した以外にもさまざまな機能があります。たとえば,違う言語同士が同じSilverlightアプリケーション上で動作して,さらに互いにやり取りができたりもします。このあたりの紹介はまた別の機会に譲りたいと思います。

さて次回は,開発には必須のSilverlightでの単体テストを取り上げたいと思います。

著者プロフィール

丸山和秀(まるやまかずひで)

株式会社アークウェイ システムクリエイター。趣味はドラム。社会人になりたてのころは職業はドラマーだと豪語していたが,いつのまにかシステム開発の楽しさにのめりこみ,仕事内容が職業になっていた。パッケージベンダにて金融向けパッケージソフトの開発を行うSEを経て現職へ。現在は研究開発としてRIAに取り組み中。