scalaobjectinitializationinitialization-order

object cross-references and initialization order


I have the following code:

abstract class SuperClass (cs: Seq[C]) {
  def init {}
}

object A extends SuperClass(Seq(B, C))
object B extends SuperClass(Seq(A, D))
object C extends SuperClass(Seq(A, B))
object D extends SuperClass(Seq(C, B, A))
object E extends SuperClass(Seq(B, A, B))

object Initializer {
  def init {
    A.init
    B.init
    C.init
    D.init
    E.init
  }
}

so at the beginning, because each object has inside some more things to initialize, I call

Initializer.init

and then at some point further in the program, when I use the cs parameter of an object, I get a NullPointerException because one of the objects referenced in the Seq is really null (printing out to the console shows that). Namely the references to the objects which have their init called later than the init of other objects that reference them, tend to be set to null.

This is an interesting situation. I have a supposedly any-to-any arbitrary cross-referencing here and I do not know how to properly realize the initialization without bringing it out to an external method completely (which is a break-down of encapsulation anyway). Especially that users might be given the ability to create their own singletons extending the SuperClass class.

Which is the best way to do this with as less boilerplate as possible?


Solution

  • I came up with the following solution. Well it's half a duplicate of Instantiating immutable paired objects, but the dependencies defined by Seq is an additional dimension.

    abstract class SuperClass (cs: => Seq[SuperClass]) {
      SuperClass.collected += this
      def init {}
    }
    object SuperClass {
      private val collected = ListBuffer[SuperClass]()
      def init = collected.foreach(_.init)
    }
    object Initializer {
      def init {
        A // access the root object
        SuperClass.init // call init on all automatically created dependent objects
      }
    }