IronPythonで式評価 その3
そもそも、IronPythonの評価式上(eval)で"DateTime.Now"をどう書くかすら判らない状態だ。(そもそも評価式中でも有効な、.NET Frameworkのラィブラリィのインポートが書けるのだろうか? 書き方があるのであれば、どなたか、是非教えて頂けないだろうか)
と弱音を吐いたのだが、Pythonのリファレンスを調べたらあっさり解決した。Evaluateメソッドを以下のように書き直しただけだ。(compileも意味無く使っても仕方が無いので、シンプルにEvaluate一発とした)
public object Evaluate(string exp, IDictionaryctx, object root) { this.engine.Globals["root"] = root; this.engine.Globals["exp"] = exp; this.engine.Execute("import System"); return this.engine.Evaluate("eval(exp)", this.engine.DefaultModule, ctx); }
答えは簡単、Pythonには元々globalsという名前のグローバル変数用の辞書があり、IronPythonではデフォルトでは公開されているPythonEngine::Globalsプロパティがそうなのだが、私は使い方も知らずにモジュール(EngineModule)を作ったため、モジュールスコープのグローバル変数用辞書に各種値をセットしていたのに、肝心のPythonEngineクラス側の辞書には変数がセットされていなかったわけだ。モジュールも無理に作る必要は無かった。全くPythonに無知なのがばればれで恥ずかしい。それにしてもこの辞書がGlobalsという公開されたプロパティだったおかげで、一発で問題が解った。デバッガさま様だ。
この修正により、以下のようにSystem名前空間のオブジェクトであるSystem.DateTime.Now等の.NET Frameworkの語彙も直接評価式として評価、インジェクションすることができるようになった。
System.DateTime.Now
これで問題は必要なアセンブリ毎にその都度importが必要なこと位にだが、これはそもそも他のスクリプトによる式評価でも発生することだ。