0

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?

kiritsuku
  • 52,967
  • 18
  • 114
  • 136
noncom
  • 4,962
  • 3
  • 42
  • 70
  • possible duplicate of [Instantiating immutable paired objects](http://stackoverflow.com/questions/7507965/instantiating-immutable-paired-objects). In short: `abstract class SuperClass (cs: => Seq[SuperClass])` – kiritsuku Feb 09 '13 at 16:08
  • @sschaef: umm.. have you tried that? I can't get it to work. The Seq is build prior to passing it as a by-name anyway. And according to the chicken-egg example, I have to make the Seq lazy when constructing it. But I am constructing it while passing it to the constructor, so I can't make it lazy. And defining it as lazy elsewhere does not look too attractive either... yeah, I just don't get it! – noncom Feb 10 '13 at 16:40
  • What exactly is not working for you? This works: https://gist.github.com/sschaef/4750334 – kiritsuku Feb 10 '13 at 17:32
  • @sschaef finally, I have succeeded in applying the proposed solution. The problem was that my code is far more complex than the example and I have missed some important changes in the code, needed to apply the solution. – noncom Feb 11 '13 at 10:57

1 Answers1

1

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
  }
}
Community
  • 1
  • 1
michael_s
  • 2,515
  • 18
  • 24
  • Well, you have improved the initialization routine.. but seems like that does not solve the initialization order problem, as far as I understand it simply automates the initialization.. also see my comment to the sschaef's comment to the original question... – noncom Feb 10 '13 at 16:43
  • Who said the objects had to be initialized in order? Also - yes - my solution would only initialize those objects that are connected to A. But this is a bit more generic than initializing each object individually. And you probably would also have a starting point or root object to use in an application... so. It depends how the whole thing would be used. Your above comment states you don't get it - OK... – michael_s Feb 10 '13 at 16:56