Scala allows you to make early definitions like so:
trait A {
val v: Int
}
class B extends { val v = 4 } with A
What is an example use of this feature?
Scala allows you to make early definitions like so:
trait A {
val v: Int
}
class B extends { val v = 4 } with A
What is an example use of this feature?
Whenever the value is used for the trait initialization. So for eaxmple for this trait:
trait UsefulTrait {
val parameter : Int
private val myHelperObject = new MyExpensiveClass(parameter)
}
The parameter is used to substitute for a constructor parameter. However the parameter should be rather made an abstract method, because it leaves more free space to the implementer.
Let's see a example from the Programming in Scala book (page 451). If we have a definition like this:
trait RationalTrait {
val numerArg: Int
val denomArg: Int
}
Then numerArg and denomArg are called abstract vals & the trait can be used directly without extends, like this:
val x = new RationalTrait {
val numerArg = 1
val denomArg = 2
}
Or
val y = new {
val numerArg = 1
val denomArg = 1
} with RationalTrait
The above two are both valid Pre-initializing of abstract val in trait, except that when you need to put an expression value to abstract vals, you can only use the later form, like this:
val z = new {
val numerArg = 1 * x
val denomArg = 2 * x
} with RationalTrait
Another interesting example in book is to Pre-initialized fields in a class definition.
class RationalClass(n: Int, d: Int) extends {
val numerArg = n
val denomArg = d
} with RationalTrait {
def + (that: RationalClass) = new RationalClass(
numer * that.denom + that.numer * denom,
denom * that.denom
)
}
In unit tests in particular, you are interested on testing traits in isolation. In this case, you need to create an Object mixed in with the trait you are interested. This is an example:
trait Display {
def show(msg: String) = ...
}
val o = new Object with Display
o.show("hey!")
Another scenario is when your trait depends on injected variables:
trait Logging {
val stream: java.io.OutputStream
def log(msg: String) = ...
}
val o = new { val stream = new FileOutputStream(...) } with Logging
o.log("hey!")