Python Workshop the Edge 2007でIronPythonのHands-onを担当したのは前回の記事で説明しましたす。このHands-on用に公開したサンプルにファイルムーバーサンプルがあります。このサンプルを動作させると以下のようなWindows Formsが起動します。
このサンプルの特徴は以下のようなものです。
回答サンプルに「filemover2.py」があります。この回答サンプルの特徴は、以下のようなクラスを持つことです。
FileSystemWatcherクラスの特徴は、ファイルシステムjに対する変更をイベントハンドラで監視することができることです。このためファイル作成イベント(Created)ハンドラのなかで、作成されたファイルを指定したフォルダへ移動しています。ここで1つの問題があります。それはフォームのリストボックスへ文字列を追加することです。C#やVBなどの.NET対応の言語をご存じの方であれば、フォームのメソッドをInvokeしなければいけないというのがピンと来ると思います。そうなんです、これを実現するにはデリゲートを使わないといけないのです。何故なら、以下の理由があるからです。
これをIronPythonでどのように実現しようかと、少し悩みました。何故なら、IronPythonではデリゲートの型を定義できないからです(方法が無くはありませんが、少し面倒です)。少しだけ考えた結果、以下のような記述をしました。
#Wacherクラス内のmovefileメソッドです def movefile(self, filename): ''' ファイルの移動を行う ''' # フォームのメソッドへInvoke(delegate) # 変数outは、フォームのインスタンスを持つ self.out.output(filename)
#Appクラス内のoutputメソッドです def output(self, msg): ''' ファイル移動メッセージの委譲処理 ''' # Watcherクラスのイベントハンドラから呼ばれます self.lb1.Items.Add(msg + u"を移動しました")
シンプルにAppクラス内のメソッドを呼び出しているだけです。C#などではAppクラス内でDelegateのインスタンスを作成して、Invokeしなければなりません。何故、このような記述で実現できたかたと言うと、IronPythonの実装ではメソッド呼び出しをデリゲートに委譲しているからです。IronPythonのソースコードを見て、このことを知っていたのでこのような記述を思いついたのです。
これは私がIronPythonを気に入っている理由の一つでもあります。同じようにデリゲートをPowerShellで呼び出そうとすると中々と込み入った細工をする必要があります(PowerShell標準でデリゲート呼び出しをサポートしていないためです)。
このような特徴がIronPythonにありますので、DLRでも同じような特徴を持つことが考えられます。まだまだDLRは仕様が固まっていませんが、IronPython2.0A2では問題なくfilemover.2pyを実行することができました。