Как мы можем переопределить конструкт реагирования актеров скалы?

Обычный способ определения типа сообщения, полученного в акторах 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 имеет тот же номер и тип параметров, что и конструктор.

Другие вопросы по тегам