Programming in the Scala 2d editor introduces the concept of type self in section 29.4 "Separation of modules into a sign":
A SimpleFoods feature might look like this:
trait SimpleFoods { object Pear extends Food("Pear") def allFoods = List(Apple, Pear) def allCategories = Nil }
So far, so good, but unfortunately, the problem arises if you try to define the SimpleRecipes property as follows:
trait SimpleRecipes { // Does not compile object FruitSalad extends Recipe( "fruit salad", List(Apple, Pear), // Uh oh "Mix it all together." ) def allRecipes = List(FruitSalad) }
The problem here is that Pear is in a different sign from using it, so it goes beyond that.
The compiler does not know that SimpleRecipes only mixes with SimpleFoods .
However, you can tell this to the compiler. Scala provides a self type for this situation.
Technically, the self type is the intended type for this when it is mentioned in the class .
Pragmatically, the self type sets requirements for any particular class; this attribute is mixed with .
If you have a trait that is used only when it is mixed with another trait or traits, you can indicate that these other traits should be used.
In this case, it is enough to specify the self type SimpleFoods , as shown:
trait SimpleRecipes { this: SimpleFoods => object FruitSalad extends Recipe( "fruit salad", List(Apple, Pear), // Now Pear is in scope "Mix it all together." ) def allRecipes = List(FruitSalad) }
Given the new type of self, Pear is now available.
Implicitly, a link to Pear is considered this.Pear .
This is safe because any particular class that mixes in SimpleRecipes must also be a subtype of SimpleFoods , which means Pear will be a member.
Abstract subclasses and traits should not follow this restriction, but since they cannot be created using the new one, there is no danger that this.Pear reference this.Pear not be executed