0

I'm looking at some Scala code in the Akka codebase, and this code snippet below is responsible for handling an Exception.

override val supervisorStrategy =
OneForOneStrategy(loggingEnabled = false) {
  case e @ InvalidAssociation(localAddress, remoteAddress, reason) ⇒
    log.warning("Tried to associate with unreachable remote address [{}]. " +
      "Address is now gated for {} ms, all messages to this address will be delivered to dead letters. Reason: {}",
      remoteAddress, settings.RetryGateClosedFor.toMillis, reason.getMessage)
    endpoints.markAsFailed(sender(), Deadline.now + settings.RetryGateClosedFor)
    AddressTerminatedTopic(context.system).publish(AddressTerminated(remoteAddress))
    Stop

  case ShutDownAssociation(localAddress, remoteAddress, _) ⇒
    log.debug("Remote system with address [{}] has shut down. " +
      "Address is now gated for {} ms, all messages to this address will be delivered to dead letters.",
      remoteAddress, settings.RetryGateClosedFor.toMillis)
    endpoints.markAsFailed(sender(), Deadline.now + settings.RetryGateClosedFor)
    AddressTerminatedTopic(context.system).publish(AddressTerminated(remoteAddress))
    Stop

The code on line 3, case e @ InvalidAssociation - InvalidAssociation is indeed an exception type, but why is the e @ necessary and what does it do?

Aaronontheweb
  • 8,224
  • 6
  • 32
  • 61
  • @DonRoby didn't show up in any search results when I looked, regardless. – Aaronontheweb Mar 29 '14 at 21:01
  • 1
    It's somewhat difficult to search for things like '@'. Completely understandable! – Don Roby Mar 29 '14 at 21:09
  • @DonRoby agreed whole-heartedly! – Aaronontheweb Mar 29 '14 at 21:16
  • 1
    If you use quotes, then symbols are searched properly - e.g. search for `scala "@"` works, but search for `scala @` doesn't. I only just found this out by accident, though with hindsight it is mentioned in the [search help](https://stackoverflow.com/help/searching) – DNA Mar 29 '14 at 21:31

1 Answers1

4

It's a bind operator. It allows you to assign an identifier to some complex pattern-matched value, so - for example - when pattern matching against case class, you can refer to both the fields of that case class as well as to the case class instance itself:

case class Record(intField: Int, stringField: String)

val something: Any = ...
something match {
   case entireInstance @ Record(intField, stringField) =>
       println(s"$entireInstance has fields $intField and $stringField")
}
ghik
  • 10,706
  • 1
  • 37
  • 50
  • Aha! That makes sense - so instead of just pattern matching the internals of the case object, I can bind an alias to the entire case object itself. Thank you! – Aaronontheweb Mar 29 '14 at 21:08
  • It's also helpful when dealing with `Options` within case classes, e.g.,: `f @ Foo(Some(id), _, _)` when you just want to match for `Foos` with a defined ID. – Ryan Mar 29 '14 at 21:40