【问题标题】:How can we override the react construct of scala actors?我们如何覆盖 scala actor 的 react 构造?
【发布时间】:2012-11-14 22:55:49
【问题描述】:

检测scala actor中接收到的消息类型的常用方法是通过

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

但是,我想知道我们如何覆盖这个 react 构造的实现,以便我们可以对收到的消息进行隐式记录。

我正在尝试实现下面提到的用例 -> 1.在消息与任何案例类匹配之前,我想在控制台/文件上写一个日志语句来显示消息的出现。 2. 我们可以通过 println() / log4j logging 显式记录这些消息。但是,我想为 scala 演员设计一个通用记录器,它将记录所有发送或接收的消息。

这方面的任何帮助都会有所帮助。 提前致谢

【问题讨论】:

标签: scala remote-actors act


【解决方案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 特性之上的语法糖;它只是为了节省您的打字时间。例如,请参阅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的参数数量和类型是否与构造函数相同。

【讨论】:

    【解决方案2】:
    //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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-03-15
      • 2023-03-06
      • 2014-04-11
      • 2017-11-10
      • 2021-01-03
      • 2019-02-26
      • 1970-01-01
      相关资源
      最近更新 更多