Как мы можем переопределить конструкт реагирования актеров скалы?
Обычный способ определения типа сообщения, полученного в акторах scala, заключается в
loop{
react{
case x: String =>
}
}
Тем не менее, я хочу знать, как мы можем переопределить эту реализацию реагирующей конструкции, чтобы мы могли выполнять неявную регистрацию полученного сообщения.
Я пытаюсь реализовать описанный ниже вариант использования -> 1. Прежде чем сообщение сопоставляется с любым классом вариантов, я хочу записать в консоль / файл оператор журнала, показывающий наличие сообщения. 2. Мы можем записывать эти сообщения явным образом с помощью функции println() / log4j. Тем не менее, я хочу создать общий регистратор для актеров Scala, который будет регистрировать все отправленные или полученные сообщения.
Любая помощь в этом отношении будет полезна. заранее спасибо
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;
}
}
Во-первых, имейте в виду, что библиотека актеров 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
это класс дела, ответ на который вы не можете (по замыслу). Класс case - это просто синтаксический сахар поверх обычных функций 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
имеет тот же номер и тип параметров, что и конструктор.