-prototype
JavaScriptのprototypeという概念は、面白く、かつRhinoやSpiderMonkeyといったエンジンをJavaやCのコードでオブジェクトのprototype操作をすると、直感的には不可能なことが可能になります。
class Person { public String getName() { return "Maya"; } } class Car { public String beep() { return "beee"; } } public void testPrototype() { Context cx = Context.enter(); Scriptable scope = cx.initStandardObjects(); Scriptable maya = cx.getWrapFactory().wrapAsJavaObject( cx, scope, new Person(), Person.class); Scriptable car = cx.getWrapFactory().wrapAsJavaObject( cx, scope, new Car(), Car.class); maya.setPrototype(car); ScriptableObject.putProperty(maya, "maya", obj); Object ret1 = cx.evaluateString(scope, "maya.name", null, 0, null); // maya.name というスクリプトが実行され、結果が「Maya」 assertEquals("Maya", Context.toString(ret1)); Object ret2 = cx.evaluateString(scope, "maya.beep", null, 0, null); // maya.beep というスクリプトが実行され、結果が「beee」 assertEquals("beee", Context.toString(ret2)); Context.exit(); }
Javaクラスである、「Person」と「Car」には継承関係がありません。しかし、これらオブジェクトを、JavaScriptのオブジェクトにして、setPrototype()メソッド(もしくは、JavaScriptにて、maya.__prototype__ = car; )にてprototype設定するとあたかも継承したかのように動作します。
Mayaではこの機能を用いて、テンプレートや.mayaファイルのモデルオブジェクトを、ルートのスコープ(JavaScript的にはスコープ、JSR223的にはNamespaceというモノ)の機能の重層化を行いました。OGNLではトリッキーな方法でやってたのですが、こちらはエンジン機能で用意されているのでコードもシンプルです。他のスクリプト言語にこの機能があるかは調べていません。Groovyとかでは、ちょっと見たぐらいでは見つからなかったのですが、どうなのでしょう?継承というよりは変数や関数のスコープを後操作できる仕組みがあって、エンジンAPIでその操作が外部からできればOKです。