0

scala アクターで受信したメッセージのタイプを検出する通常の方法は、

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

ただし、受信したメッセージの暗黙的なログを記録できるように、react コンストラクトのこの実装をオーバーライドする方法を知りたいです。

以下のユース ケースを実装しようとしています -> 1. メッセージがケース クラスに一致する前に、メッセージの発生を示すログ ステートメントをコンソール/ファイルに書き込みたいと考えています。2. これらのメッセージは、println() / log4j logging によって明示的にログに記録できます。ただし、送受信されたすべてのメッセージをログに記録する scala アクター用の汎用ロガーを設計したいと考えています。

この点に関するヘルプは役に立ちます。前もって感謝します

4

2 に答える 2

1

まず、Scala アクター ライブラリは廃止され、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場合、答えは (設計上) できないということです。ケースクラスは、通常の Scala 機能の上にある単なる構文糖衣です。入力を節約するためだけに存在します。たとえば、この質問を参照してください。

ただし、パターンマッチングとメソッド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は、コンストラクターと同じ数と型のパラメーターがあるかどうかを確認してください。

于 2012-11-14T23:08:03.980 に答える
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;
    }
}
于 2012-11-16T18:18:28.583 に答える