2012-11-14 55 views
0

的檢測斯卡拉演員收到消息的類型通常的方法是通過我們如何覆蓋scala actors的反應結構?

loop{ 
    react{ 
      case x: String => 
      } 
    } 

不過,我想知道我們如何可以覆蓋這個實現的反應構造,使我們可以做到信息的隱含日誌記錄收到。

我想實現下面提到的用例 - > 1.在消息與任何case類匹配之前,我想在控制檯/文件上寫一條日誌語句來顯示消息的發生。 2.我們可以通過println()/ log4j日誌顯式地記錄這些消息。但是,我想爲scala actors設計一個通用記錄器,它將記錄所有發送或接收的消息。

在這方面的任何幫助將有所幫助。 在此先感謝

+2

相關? http://stackoverflow.com/questions/13329535/implicitly-logging-messages-received-by-an-actor-in-scala – Brian

回答

1

首先,請注意,斯卡拉演員圖書館已被棄用,以支持Akka。因此,這個答案不會很有幫助(雖然其他演員圖書館將繼續可用一段時間 - 並且因爲如果人們想維護它,它永遠是開源的)。

無論如何,react方法在scala.actors.Actor中定義。只是無法導入它,或者用你自己的方法隱藏它。你自己什麼

那麼,該方法只需要一個PartialFunction[Any,Unit]。所以,你還應該:

def react(pf: PartialFunction[Any,Unit]): Nothing = { /*how?;*/ Actor.react(/*what?*/) } 

你真的只能訪問部分功能,你必須推遲到Actor.react做你想做什麼。所以你需要將pf換成另一個PartialFunction來執行你的日誌記錄。所以,你可以

val qf = new PartialFunction[Any,Unit] { 
    def isDefinedAt(a: Any) = pf.isDefinedAt(a) 
    def apply(a: Any): Unit = { 
    log(a) // Maybe add more logic to know what a is 
    pf(a) 
    } 
} 

如果你想看到進來並得到檢驗,但實際上並沒有消費的消息,你可以做更多與isDefinedAt也。

所以,很顯然的是,我希望,/*how?*/是上述定義(創建)qf/*what?*/只是qf

如果你想知道a是否是案例類,答案是你不能(通過設計)。 case class只是普通Scala特性之上的語法糖;它只是爲了節省你打字。例如參見this question

但是,你可以得到相當接近通過模式匹配爲Product並檢查它是否有copy方法:

case class M(i: Int) 
val a: Any = M(5) 

scala> a match { 
    case p: Product if p.getClass.getMethods.exists(_.getName=="copy") => println("Yes") 
    case _ => println("No") 
} 
Yes 

如果你真的想獲得幻想,檢查是否copy具有相同數量和類型參數作爲構造函數。

1
//Following is a code for a logReact Method that does the same thing as react but also logs the message received hope this works for you 
import scala.actors.Actor; 
import scala.actors.Actor._ 

trait ActorLogging extends Actor { 
    def logReact(handler: PartialFunction[Any, Unit]): Nothing = { 
     val handler2: PartialFunction[Any, Unit] = { 
      case x => 
       println("Inside Logs -- with message recieved -- " + x.toString); 
       handler.apply(x); 
     } 
     super.react(handler2) 
    } 
} 

class sumAct extends Actor with ActorLogging { 
    def act() { 
     loop { 
      logReact { 
       case a: Int => 
        println("Inside actor Sum Act Received the message -- " + a) 
        exit; 
      } 
     } 
    } 
} 

object ActorLog { 
    def main(args: Array[String]): Unit = { 
     var s: sumAct = new sumAct; 
     s.start(); 
     s ! 1.toInt; 
    } 
}