1

I have this question based on the Akka Concurrency pre-print (the final version isn't available yet), where this is used without explanation.

In version 1 of the class, they have:

class Altimeter extends Actor with ActorLogging with EventSource{
...
}

The claim is that Altimeter is now closely couple with EventSource, so testing Altimeter requires also testing EventSource. The suggested change to fix that is as follows:

--- a/src/main/scala/Altimeter.scala
+++ b/src/main/scala/Altimeter.scala
@@ -9,9 +9,10 @@ import  scala.concurrent.ExecutionContext.Implicits.global
 object Altimeter{
   case class RateChange(amount: Float) //sent to Altimeter
   case class AltitudeUpdate(altitude: Double)
+  def apply() = new Altimeter with ProductionEventSource
 }

-class Altimeter extends Actor with ActorLogging with EventSource{
+class Altimeter extends Actor with ActorLogging{ this: EventSource =>
   import Altimeter._

   val ceiling = 43000       //feet
diff --git a/src/main/scala/EventSource.scala b/src/main/scala/EventSource.scala
index 1fd5578..ded4f38 100755
--- a/src/main/scala/EventSource.scala
+++ b/src/main/scala/EventSource.scala
@@ -8,7 +8,12 @@ object EventSource{
   case class UnregisterListener(listener: ActorRef)
 }

-trait EventSource { this: Actor =>
+trait EventSource{
+  def sendEvent[T](event: T): Unit
+  def eventSourceReceive: Actor.Receive
+}
+
+trait ProductionEventSource { this: Actor =>
   import EventSource._

My first problem is that I don't understand what this: SomeTraitType => accomplishes. Is it literally saying that the class is of type SomeTraitType?

My second question is, what's the difference between that and using extends SomeTraitType, and why is it advantageous? Perhaps that would be obvious if I knew it the former meant.

anchorite
  • 75
  • 4
  • possible duplicate of http://stackoverflow.com/questions/1990948/what-is-the-difference-between-scala-self-types-and-trait-subclasses – pagoda_5b Feb 16 '13 at 09:25

1 Answers1

6

That notation (this: EventSource => ...) is called a "self-type annotation" and it constrains the way a trait may be mixed into another inheritance structure. Any name (not just this) may be used. self is another common one.

This use is, more or less, the Cake pattern (or a simplification thereof). With that terminology, you can find many resources that will help explain its use.

Another use of a self-type annotation (usually unconstrained, simply self => ...) creates an alias for this that can be used in a nested scope (nested class) where the outer this is masked.

Randall Schulz
  • 26,420
  • 4
  • 61
  • 81