2013-01-09 10 views
6

Qui sto utilizzando la libreria di attori Akka. La libreria degli attori definisce una funzione parziale "ricevere" che un attore che estende "attore" deve implementare per gestire vari messaggi. Sto creando una gerarchia dei tratti per la mia applicazione in cui tratto "clockActor" estende Actor e "MasterClock" e "SubClock" estendono "clockActor". Sto cercando di aggiungere la funzionalità comune degli orologi alla funzione di ricezione del tratto "orologio", ma come aggiungere funzionalità extra alla funzione di ricezione nei tratti master e sub clock?Estensione di una funzione parziale parzialmente implementata in scala

In breve, ho bisogno di un modo per aggiungere istruzioni caso supplementari a una funzione parziale. Idee?

+2

È possibile comporre funzioni parziali con [ 'orElse'] (http://www.scala-lang.org/api/current/index .html # scala.PartialFunction). Avrebbe fatto il trucco? – 4e6

+0

Non proprio. La libreria di akka fa tutto ciò che è il suo messaggio chiamando internamente, quindi non posso entrare e aggiungere una risposta alla chiamata. – Alex

+0

infatti, sì, oElse fa esattamente ciò di cui ho bisogno. Sconosciuto googling e solo raccogliendo il primo risultato ha fatto sembrare diverso ma ora ho funzionato. – Alex

risposta

11

Come già suggerito, si potrebbe facilmente comporre PartialFunctions usando orElse

trait ClockActor { 

    def commonOp = { 
     case ... => ... 
    } 

} 

class MasterClock extends Actor with ClockActor { 

    def receive = commonOp orElse masterOp 

    def masterOp = { 
     case ... => ... 
    } 

} 

class SubClock extends Actor with ClockActor { 

    def receive = commonOp orElse subOp 

    def subOp = { 
     case ... => ... 
    } 

} 
1

Una cosa che viene in mente è quello di fare qualcosa di simile:

trait ClockActor { 
    def pf:PartialFunction[String, Boolean] = { 
    case "a" => true 
    case v if(_pf.isDefinedAt(v)) => _pf.apply(v) 
    } 

    def _pf:PartialFunction[String, Boolean] = Map.empty 
} 

object MasterClock extends ClockActor { 

    override def _pf:PartialFunction[String, Boolean] = { 
    case "b" => false 
    } 

    println(pf("a")) 
    println(pf("b")) 

} 

che sarà in uscita:

scala> MasterClock 
true 
false 

Il valore true deriva dalla definizione della funzione parziale del Trait ClockActor , il false proviene dall'oggetto MasterClock.

+0

Sì, questo funziona. Mi sembrava di avere l'idea che quando "esegui l'override" di una funzione, non puoi toccare l'originale. Se devo farlo, userò questo modo di fare le cose, ma sto cercando un modo in cui le persone che stanno implementando le sottoclassi non debbano preoccuparsi di chiamare super o qualsiasi implementazione nel tratto genitore. – Alex

+0

@Alex, ho fatto una modifica rapida che potrebbe aiutare di più con quello che stai cercando di realizzare. Ho cambiato il tratto per avere due funzioni, una 'pf' che sarebbe pubblica e' _pf' che è di default vuota e sarebbe sovrascritta nella classe come necessario. È essenzialmente uguale a quello che avevo prima, ma in questo modo l'utente non deve preoccuparsi di chiamare super poiché le chiamate pubbliche sarebbero alla funzione 'pf' del carattere. – jcern

+0

Hai una versione funzionante ma in un modo completamente diverso. classe 'MasterNode estende TreeNode { def masterReceive: Ricevi = { caso "specificBehaviour"=> {println ("sto comportando come un maestro")}} di override def ricevere = masterReceive OrElse super.receive } ' Dove ricevere è il metodo che sono obbligato ad implementare nel tratto genitore e creo appena una nuova funzione parziale per il nuovo comportamento nella sottoclasse e li concatena con oElse. – Alex