2012-12-13 9 views
5

Sono novizio in rinoceronte.Come abilitare 'for ... in' my NativeJavaObject in Rhino?

Attualmente sto utilizzando il framework di Rhino 1.7R tramite .NET 4 e IKVM.NET. Ho esposto diverse classi wrapping implementando NativeJavaObject usando l'API setWrapFractory().

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; 
    } 

    ..... 
} 

Ora, posso accedere a tutti i metodi e proprietà .NET come volevo.

Il mio problema attuale è supportare 'per ... nelle' mie classi NativeJavaObject. Quando ho valutare

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

esso restituisce 'no 'a' invito a non-oggetto' errore.

Sembra che la funzione di 'arrivare' il tentativo di cercare un oggetto di '_ iteratore _', ma si è tradotto in 'non trovato' a get(). Quindi, finisce con l'eccezione. . Finora, ho cercato

  • aggiunto java.util.Iterator
  • this.getIds di ritorno() GetEnumrator();

Nessuno dei lavori.

Come è possibile consentire l'accesso di enumrate di proprietà per Wrapped NativeJavaObject? Qual è il valore di ritorno previsto di Rhino di '_ iteratore _' abilitare 'per ... in'?

Grazie in anticipo!

risposta

2

__iterator__ fa parte di un Mozilla specific language extension. Questo collegamento spiega che il metodo __iterator__ restituisce un oggetto con un metodo next che genera StopIteration quando l'iteratore è esaurito.

Devi opt in di iteratori e generatori però:

Per abilitare JavaScript 1.7 supporto, è necessario impostare la versione da 170 utilizzando la chiamata Context.setLanguageVersion() API. Se si utilizza la shell di Rhino, è possibile specificare -version 170 sulla riga di comando o chiamare la versione (170) nel codice eseguito dalla shell.

È possibile scrivere JS in Rhino che vi avvolgerà un iteratore Java per presentarlo come un iteratore JS:

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

In alternativa, è possibile utilizzare i generatori di stile Mozilla, ma penso che è necessario crea l'interprete di Rhino con un'opzione per abilitarli.

Mentre gli iteratori personalizzati sono uno strumento utile, la loro creazione richiede un'attenta programmazione a causa della necessità di mantenere esplicitamente il proprio stato interno.I generatori forniscono un'alternativa potente: consentono di definire un algoritmo iterativo scrivendo una singola funzione che può mantenere il proprio stato.

Un generatore è un tipo speciale di funzione che funziona come una fabbrica per gli iteratori. Una funzione diventa un generatore se contiene una o più espressioni di rendimento.

+0

Grazie mille. "__iterator___" cercava una funzione da elaborare, non l'oggetto autonomo. Proverò anche con setLanguageVersion (170). Grazie ancora per aver fornito informazioni molto utili! –

+0

Alla fine ho eseguito l'iterazione di NativeJavaObject creando la classe Iterator come 'ScriptableObject'. Ora esegue 'for (var a in document) {}' e 'if (' location 'nella finestra) {}'. Grazie ancora! –

+0

@ Sì, prego. Scripting felice. –