Defining a val in terms of the member of an abstract val (Scala bug?)

estolua

I came across a runtime error and was wondering whether this is a bug in Scala, or if it shouldn't at least be caught during compile time. This code produces a NullPointerException:

object Main extends App {
  trait A {
    val data: { val x: Int }
    val x = data.x
  }
  val a = new A {
    val data = new Object { val x = 42 }
  }
  a.x
}

Of course it's easy to fix by making A.x lazy or a def, but as obvious as that may be in this minimal example, in more realistic code it can be a little perplexing.

Jens Halm

This is confusing when you encounter it for the first time, but it is expected behaviour.

The normal initialization order is that vals in super traits are initialized first. In your example this means that val x in trait A gets initialized before val data in your anonymous subclass, therefore causing a NullPointer.

If you want to make your example work you have to use a feature called "Early Defintions" (5.1.6 in the language specification).

In your concrete example this is the syntax you'd need to use:

val a = new {
  val data = new Object { val x = 42 }
} with A  

This initializes the data val before initializing the vals in A.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related