2013-01-09 19 views
6

Używam tutaj biblioteki aktorów Akka. Biblioteka aktorów definiuje funkcję częściową "odbiór", którą aktor, który rozszerza "aktora", musi zaimplementować, aby radzić sobie z różnymi komunikatami. Tworzę hierarchię cech dla mojej aplikacji, w której cecha "clockActor" rozszerza Aktora, a "MasterClock" i "SubClock" rozszerzają "clockActor". Chciałbym dodać wspólną funkcjonalność zegarów do funkcji odbierania "funkcji zegara", ale w jaki sposób mogę dodać dodatkową funkcjonalność do funkcji odbierania w cechach głównych i podrzędnych?Rozszerzanie częściowo zaimplementowanej funkcji częściowej w scala

W skrócie, potrzebuję sposobu na dodanie dodatkowych instrukcji case do częściowej funkcji. Pomysły?

+2

można komponować funkcja częściowa z [ 'orElse'] (http://www.scala-lang.org/api/current/index .html # scala.PartialFunction). Czy to wystarczy? – 4e6

+0

Niezupełnie. Biblioteka akka robi wszystko, co jest w wiadomościach, wywołując odbiór wewnętrznie, więc nie mogę w tym celu wstawić orElse do połączenia. – Alex

+0

w rzeczywistości tak, orElse robi dokładnie to, czego potrzebuję. Zaniedbanie googlowania i tylko wybieranie pierwszego wyniku sprawiło, że wyglądało inaczej, ale mam to teraz działa. – Alex

Odpowiedz

11

Jak już sugeruje, można łatwo komponować PartialFunctions użyciu 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

Jedną rzeczą, która przychodzi do głowy, to zrobić coś takiego:

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")) 

} 

który wyświetli:

scala> MasterClock 
true 
false 

Wartość true pochodzi z definicją w częściowym funkcji cecha ClockActor , false pochodzi z obiektu MasterClock.

+0

Tak, to działa. Wydawało mi się, że kiedy "przesłonisz" funkcję, nie możesz dotknąć oryginału. Jeśli będę musiał wtedy wykorzystam ten sposób robienia rzeczy, ale szukam raczej sposobu, w jaki ludzie, którzy wdrażają podklasy, nie muszą przejmować się wywołaniem super lub jakiejkolwiek implementacji w cechach rodzica. – Alex

+0

@Alex, zrobiłem szybką edycję, która może pomóc ci bardziej w tym, co chcesz osiągnąć. Zmieniłem cechę na dwie funkcje: jedną 'pf', która byłaby publiczna, oraz' _pf', która jest domyślnie pusta i w razie potrzeby zostanie nadpisana w klasie. Zasadniczo jest to to samo, co wcześniej, ale w ten sposób użytkownik nie musi się martwić o wywołanie super, ponieważ publiczne wywołania będą związane z funkcją 'pf' tej cechy. – jcern

+0

Masz wersję działa, ale w zupełnie inny sposób. 'klasa MasterNode rozciąga TreeNode { def masterReceive: Otrzymuj = { przypadek "specificBehaviour"=> {println ("ja zachowuje się jak mistrz")}} przesłanianie def otrzymać = masterReceive OrElse super.receive } ' ' Gdzie odbiór jest metodą, którą muszę wprowadzić w cechę nadrzędną i po prostu tworzę nową funkcję częściową dla nowego zachowania w podklasie i łączę je za pomocą orElse. – Alex