2014-10-07 20 views
8

Voglio fare delle cose funky simili a chiusure. Voglio un metodo per restituire un oggetto anonimo le cui viscere fanno riferimento ai parametri del metodo. Ecco il codice che ho scritto che illustra il mio intento:La funzione Scala che restituisce un oggetto anonimo?

object SessionManagement { 

    implicit class SessionManagementExtensions(val c : ChainBuilder) { 

    def set(dest: String) = object { 

     def from(src: String) = 
     c.exec(session => { 
      val list = session(src).as[Vector[String]] 
      val i = if (list.size == 0) -1 else Random.nextInt(list.size) 
      val value = if (i > 0) list(i) else "INVALID_" + dest 
      session.set(dest, value) 
     }) 

     def to[T](v: Expression[T]) = 
     c.exec(session => session.set(dest, v)) 

    } 

} 

Quello che sto cercando di fare è avere una chiamata al "set" restituire un oggetto che mi permette di poi concatenare una chiamata a" .to ", in questo modo:

.set(SOMETHING).to(OTHER) 

Ma non posso dire

def foo = object { ... } 

c'è un modo a Scala per ottenere quello che sono dopo? Devo definire una classe e creare un'istanza?

+0

Quindi si desidera che il tipo restituito di 'set' sia' {def from (src: String): Unit; def per [T] (v: Expression [T]): Unit} '? –

risposta

8

Si può semplicemente restituire un nuovo oggetto anonimo. La sintassi era quasi giusto: basta sostituire object da new:

def set(dest: String) = new { 
    def from(src: String) = 
    ... 

    def to[T](v: Expression[T]) = 
    ... 
} 

Tuttavia, questo darà un tipo strutturale a sito di chiamata, che dovrà utilizzare la reflection per utilizzare i metodi. Per evitare questo, definire un tratto con l'API del vostro oggetto:

trait SetResult { 
    def from(src: String): ReturnTypeOfFrom 
    def to[T](v: Expression[T]): ReturnTypeOfTo 
} 

def set(dest: String): SetResult = new SetResult { 
    def from(src: String) = 
    ... 

    def to[T](v: Expression[T]) = 
    ... 
} 

Nota che ho usato ReturnTypeOfFrom e ReturnTypeOfSet perché non ho idea di che cosa restituiscono i vostri metodi. A proposito, questa è una cattiva abitudine: i metodi pubblici dovrebbero sempre avere un tipo di risultato esplicito.

+0

Che se ne è occupato. Grazie! –

0

Non sono sicuro di cosa vuoi fare, quindi spero che questo ti dia il punto di partenza.
Non si può avere oggetto anonimo, ma si può avere oggetti interni, in modo da poter fare:

implicit class SessionManagementExtensions(val c: ChainBuilder) { 

    object MyInnerObject { 

    def from(src: String) = 
     c.exec(session => { 
     val list = session(src).as[Vector[String]] 
     val i = if (list.size == 0) -1 else Random.nextInt(list.size) 
     val value = if (i > 0) list(i) else "INVALID_" + dest 
     session.set(dest, value) 
     }) 

    def to[T](v: Expression[T]) = 
     c.exec(session => session.set(dest, v)) 

    } 

    def set(dest: String) = MyInnerObject 

} 
Problemi correlati