I accidentally ran into a situation like this (the example is simplified to isolate the problem):
abstract class Element(val other: Element)
case object First extends Element(Second)
case object Second extends Element(First)
object Main {
def main(arguments: Array[String]) {
val e1 = First
val e2 = Second
println("e1: "+e1+" e1.other: "+e1.other)
println("e2: "+e2+" e2.other: "+e2.other)
}
}
Anyone would like to guess the output? :-)
e1: First e1.other: Second
e2: Second e2.other: null
The output makes kind of sense. Apparently at the time the Second object is created, the First one does not yet exist, therefore null
is assigned. The problem is... It's so wrong! It took me a couple of hours to track this one down. Shouldn't the compiler tell something about this?
Interestingly, when I tried to run the thing as a Scala script (the same code, minus object Main
and def main
lines, and closing }
s), I got an infinite sequence (not really infinite - at some point the list stops, I guess due to some limitation on the depth of Exception traces, or something) of exceptions like this:
vilius@blackone:~$ scala 1.scala
...
at Main$$anon$1.Main$$anon$$Second(1.scala:4)
at Main$$anon$1$First$.<init>(1.scala:3)
at Main$$anon$1.Main$$anon$$First(1.scala:3)
at Main$$anon$1$Second$.<init>(1.scala:4)
at Main$$anon$1.Main$$anon$$Second(1.scala:4)
at Main$$anon$1$First$.<init>(1.scala:3)
...
I'd love to get something at least as informative during runtime...
Ok. I finished my rant. Now I guess I should ask something. :)
So, could you recommend any nice design for case objects pointing one to another? By the way, in my real situation there are several objects pointing to the next and previous instances in circular way (the last one points to the first one and vice versa).
Using Scala 2.8.1-final
EDIT:
I found a solution for my main problem:
abstract class Element {
val other: Element
}
case object First extends Element {
val other = Second
}
case object Second extends Element {
val other = First
}
This seems to work in compiled version (but not as a Scala script!). Could anyone shed some light on what's going on here?
EDIT2: This works as a script (the same thing, just using def
s):
abstract class Element { def other: Element }
case object First extends Element { def other = Second }
case object Second extends Element { def other = First }
See Question&Answers more detail:
os