2008/12/01

GroovyでJavaScriptソースをコールしてみる2

ゲンゾウ用ポストイット: GroovyでJavaScriptソースをコールしてみるの続き。

obj.get("age", obj)と記述するのが面倒なので、なんとかしたいとおもい、metaClass.getAtにクロージャを追加してみようと考えました。

まず、javascript実行結果から取得されたオブジェクトのクラスを調べてみる。

import javax.script.*;

def engine = new ScriptEngineManager().getEngineByName("JavaScript");

engine.with{
    eval("var genzou = {age:29, sex:'man'};");

    def obj = eval("genzou")
    println obj.properties
}

プロパティをすべて舐めて出力してみた。
結果、以下のように。

["allIds":["age", "sex"], "parentScope":com.sun.script.javascript.RhinoTopLevel@1feaf06, "ids":["age", "sex"], "sealed":false, "class":class sun.org.mozilla.javascript.internal.NativeObject, "className":"Object", "maxInstanceId":0, "prototype":[object Object]]

なんか難しそうだw。allIdsって何だ??idsとの違いは分からないが、多分一緒かな。classがsun.org.mozilla.javascript.internal.NativeObjectであることだけははっきりしました。sunmozillaってどっちなんだろう(笑)

本題に。NativeObjectにgetAtメソッドを追加してみる。

import javax.script.*;

def engine = new ScriptEngineManager().getEngineByName("JavaScript");

engine.with{
    eval("var genzou = {age:29, sex:'man'};");

    // 拡張してみる
    sun.org.mozilla.javascript.internal.NativeObject.metaClass.getAt = { String key -> delegate.get(key, delegate) }

    def obj = eval("genzou")
    println obj["age"]
}

出力結果は「29.0」。おおーーできたよ!やった。

いくつか分かったことが。callしたjavascriptの結果が数値の場合には、Double型で返ってくるみたい。それから、今回はrhinoを使用していないですが、rhinoを使用した場合にはsun.org.mozilla.javascript.internal.NativeObjectの部分がorg.mozilla.javascript.NativeObjectとなるみたいです。sunのjavascript実装と、rhinoのjavascript実装の2つがあるんですね。知らずに組むと混乱しそう。

できれば、getAtメソッドを使用せず、 println obj.age みたいにプロパティ参照形式で記述したい・・・

0 件のコメント:

コメントを投稿