Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala case class is not matched in receive method (in akka actors)

I have something like this:

class ProbeActor extends Actor {
  case class Probe(messageKey: String)
  def receiveProbe: Receive = {
    case Probe(probeKey) => println("Good probe: "+probeKey)
    case x => println("Bad probe: "+ x)
  }
  final override def receive = receiveProbe orElse receiveOther
  def receiveOther: Receive = {
    case _ => println("Other")
  }
}

and I call it like this:

class Prober extends ProbeActor {
  val definite = ActorSystem("ProbeTest").actorOf(Props[ProbeActor], name = "probed")
  implicit val timeout = Timeout(5 second)
  val future = definite ? Probe("key")
}

I expect the text "Good probe: key" should be printed, but I get "Bad probe: Probe(key)".

Note: If I put the Probe case class outside, then it works fine.

like image 536
Mahdi Avatar asked Feb 08 '23 09:02

Mahdi


2 Answers

After searching more, I found an answer on scala-lang.org:

I think the underlying misconception is about the identity of nested class types.

In

class A { class B }

each new instance of class A x creates a new type x.B. And if you do the plain pattern match inside of A you are referring to the specific instance of the type B this.B.

like image 178
Mahdi Avatar answered Mar 16 '23 00:03

Mahdi


A way to pattern-match on Probe without moving it outside the class is

case probe: ProbeActor#Probe => println("Good probe: "+probe.messageKey)

Of course, moving it outside (e.g. to the companion object) is the better solution; particularly in Akka, as Archeg mentions, to avoid the direct reference to the actor.

like image 33
Alexey Romanov Avatar answered Mar 15 '23 23:03

Alexey Romanov