2012-12-13 17 views
5

Ich bin Neuling im Nashorn.Wie kann 'for ... in' mein NativeJavaObject in Rhino aktiviert werden?

Derzeit verwende ich Rhino 1.7R Framework durch .NET 4 und IKVM.NET. Ich legte mehrere umschlossene Klassen offen, die NativeJavaObject mithilfe der API setWrapFractory() implementieren.

public class InterceptNativeObject : NativeJavaObject 
{ 
    public InterceptNativeObject() 
    { 

    } 

    public override Object get(String name, Scriptable start) 
    { 
     Object res = base.get(name, start); 
     if (res is NativeJavaMethod) 
     { 
      NativeJavaMethod method = (NativeJavaMethod)res; 
      return new RhinoMethodWrapFunction(method); 
     } 
     if (res == org.mozilla.javascript.UniqueTag.NOT_FOUND && 
      base.javaObject is IPropertBox && base.javaObject != null) 
     { 
      object ret = ((IPropertBox)base.javaObject)._x__GetPropertyValue(name); 

      return Utils.ConvertCLRValueToJavaValue(ret); 
     } 
     return res; 
    } 

    ..... 
} 

Jetzt kann ich auf alle .NET-Methoden und Eigenschaften zugreifen, wie ich wollte.

Mein aktuelles Problem ist es, 'for ... in' meine NativeJavaObject-Klassen zu unterstützen. Als ich

 'for(var prop in myClass){printf(prop);};' , 

bewerten es gibt ‚Nein‚in‘Aufruf zum Nicht-Objekt‘ Fehler.

Es scheint die ‚get‘ versuchen, die Suche ein Objekt von ‚_ Iterator _‘, aber es führte zu ‚nicht gefunden‘ bei get() Funktion. Also, es endet mit Ausnahme. . Bisher habe ich versucht,

  • java.util.Iterator hinzugefügt
  • Rückkehr this.getIds() GetEnumrator();

Keine der funktioniert.

Wie kann ich Eigenschaft enumrate Zugriff für meine Wrapped NativeJavaObject zulassen? Was ist Rhinos erwarteter Rückgabewert von '_ Iterator _' um 'für ... in' zu aktivieren?

Vielen Dank im Voraus!

Antwort

2

__iterator__ ist Teil einer Mozilla specific language extension. Dieser Link erläutert, dass die Methode __iterator__ ein Objekt mit einer next-Methode zurückgibt, die StopIteration auslöst, wenn der Iterator erschöpft ist.

Sie müssen opt in zu Iteratoren und Generatoren aber:

JavaScript 1.7-Unterstützung aktivieren, können Sie die Version als 170 mit dem Context.setLanguageVersion() API-Aufruf festlegen. Wenn Sie die Rhino-Shell verwenden, können Sie in der Befehlszeile -version 170 angeben oder in Code, der von der Shell ausgeführt wird, die Version (170) aufrufen.

Sie JS in rhino schreiben können, die eine Java-Iterator wickeln wird es als JS Iterator zu präsentieren:

function javaIteratorToJsIterator(javaIterator) { 
    return { 
    next: function() { 
     if (!javaIterator.hasNext()) { throw StopIteration; } 
     return javaIterator.next(); 
    } 
    }; 
} 

Alternativ Sie Mozilla Stil Generatoren verwenden können, aber ich glaube, Sie müssen Erstellen Sie den Rhino-Interpreter mit einer Option, um sie zu aktivieren.

Während benutzerdefinierte Iteratoren ein nützliches Werkzeug sind, erfordert ihre Erstellung eine sorgfältige Programmierung, da ihr interner Zustand explizit beibehalten werden muss.Generatoren bieten eine leistungsfähige Alternative: Sie ermöglichen es Ihnen, einen iterativen Algorithmus zu definieren, indem Sie eine einzelne Funktion schreiben, die ihren eigenen Zustand beibehalten kann.

Ein Generator ist eine spezielle Art von Funktion, die als Factory für Iteratoren funktioniert. Eine Funktion wird zu einem Generator, wenn sie einen oder mehrere Yield-Ausdrücke enthält.

+0

Vielen Dank. "__iterator___" suchte nach einer zu verarbeitenden Funktion, nicht nach einem selbst-Objekt. Ich werde es auch mit setLanguageVersion (170) versuchen. Nochmals vielen Dank für die Bereitstellung sehr nützlicher Informationen! –

+0

Ich habe schließlich das NativeJavaObject iteriert, indem ich Iterator-Klasse als 'ScriptableObject' erstellt habe. Jetzt läuft 'for (var a im Dokument) {}' und 'if (' location 'im Fenster) {}'. Danke nochmal! –

+0

@Yone, Gern geschehen. Viel Spaß beim Schreiben. –