Reputation: 2366
I can't find an answer why this code throws an exception for assertProperChildren(Zoo2)
, but only if Zoo2.Tiger
is accessed before making the assert. If you comment that access line, all asserts work. Doesn't make sense to me. Is this a known Scala bug?
trait Domain {
abstract class ChildDomain
def children: Seq[ChildDomain]
}
// V1
abstract class Zoo1 extends Domain {
object Tiger extends ChildDomain
val children = Seq(Tiger)
}
object Zoo1 extends Zoo1
// V2
object Zoo2 extends Domain {
object Tiger extends ChildDomain
val children = Seq(Tiger)
}
// V3
object Zoo3 extends Domain {
object Tiger extends ChildDomain
lazy val children = Seq(Tiger)
}
object Main {
def main(args: Array[String]): Unit = {
def assertProperChildren(domain: Domain) = {
assert(!domain.children.contains(null))
}
Zoo1.Tiger
// Will NOT crash here, even if we touch Zoo1.Tiger before Zoo1
assertProperChildren(Zoo1)
Zoo2.Tiger
// Will crash here, but only if we touch Zoo2.Tiger before Zoo2
assertProperChildren(Zoo2)
// So if we want a scala object directly inheriting from a Domain
// we need lazy children:
Zoo3.Tiger
assertProperChildren(Zoo3)
}
}
Upvotes: 1
Views: 51
Reputation: 1154
Scala follows initialization order, it's explained in the below link as FAQs. https://docs.scala-lang.org/tutorials/FAQ/initialization-order.html
You can use -Xcheckinit
as part of scalac flag. To validate the same.
Upvotes: 1