Partial function interception / decoration

How to intercept a PartialFunction? for example, in actors, if I just want to print everything that comes into the following receiving method before passing it to the process method:

class MyActor extends Actor {
  def receive : Receive = process
  def process : Receive = {
    case Some(x) => /* do one thing */ ()
    case None => /* do another thing */ ()
    case _ => /* do something else */ ()
  }
}
+4
source share
3 answers

A PartialFunctionis a trait that you can implement. You should not use syntax case.

Unfortunately, it does not have a convenient method for compiling as you describe. The closest method andThen, but the argument you pass in should be a regular function, which can lead to matching errors when the argument is not processed in the actual receive function. So you are stuck in writing this long way.

class MessageInterceptor(receiver: Receive) extends Receive {
  def apply(msg: Any) = {
    /* do whatever things here */
    receiver.apply(msg)
  }
  def isDefinedAt(msg: Any) = receiver.isDefinedAt(msg)
}

val process = new MessageInterceptor(receive)
+6
def process: Receive = printMessage andThen {
  case Some(x) => /* do one thing */ ()
  case None => /* do another thing */ ()
  case _ => /* do something else */ ()
}

def printMessage: PartialFunction[Any, Any] = {
  case m => 
    println(m)
    m
}
+4

, :

def printEverything: PartialFunction[Any, Any] = {
case x =>
    println(x)
    x
}

and use it:

def receive : Receive = printEverything andThen process
+2
source

All Articles