I have an anonymous class that needs to be initialized before the trait that it mixes in. Early initialization won’t work because they don’t allow one to use the ‘this’ reference. I can make it work if I declare the class as an inner trait with a self type, but this seems unnecessarily verbose, as the type is only used in one place in the code and is inuitive to be inlined as an anonymous class. However, I seem to find the syntax that scala will accept and meets the initialization order requirements that I have. Here is a simplified example without the extraneous detail (assume there are reasons I’m doing things this way).
trait WaitCondition[+T] {
...
}
trait EventWaitCondition[+T] extends WaitCondition[T] {
...
}
trait Event { outer =>
private[this] var _cachedWaitCondition : Option[WaitCondition[T]]
def next() : WaitCondition[T] =
//Is there a way to "inline" the defintion of NextWaitCondition
//without screwing up the initialization order?
_cachedWaitCondition.getOrElse{ new NextWaitCondition with EventWaitCondition[T] }
private[this] trait NextWaitCondition { this : WaitCondition[T] =>
outer._cache = Some(this)
....
}
....
}
So, basically, my question is that is there a way to inline the definition of NextWaitCondition as an anonymous type without changing the initialization order between NextWaitCondition and WaitCondition (i.e., so that NextWaitCondition still initializes first)?
Short answer: of course not.
We must take your word that there is just cause for the bending the laws of init order. Ponder for a moment the souls who respect the law but still suffer under it.
@xiefei’s answer is not kludgy; it’s sufficiently structured to effect the kludge you seek.
There is talk about deprecating DelayedInit in favor of a postConstructor hook; but you’re really asking for a preConstructor hook, so why not just formalize that with a template method?
And depending on the dependency between your Foo and SubFoo, this could be a matter of preferring composition to inheritance. Then there are no games with init order.
In the following, Firstly generalizes your named solution with a template method. It has the advantage that only the use site knows or cares about it.