3

This is probably covered by the blog entry by Jesse Eichar—still I can't figure out how to correct the following without resorting to lazy vals so that the NPE is fixed:

Given

trait FooLike { def foo: String }
case class Foo(foo: String) extends FooLike

trait Sys {
  type D <: FooLike
  def bar: D
}

trait Confluent extends Sys {
  type D = Foo
}

trait Mixin extends Sys {
  val global = bar.foo
}

First attempt:

class System1 extends Mixin with Confluent {
  val bar = Foo("npe")
}

new System1  // boom!!

Second attempt, changing mixin order

class System2 extends Confluent with Mixin {
  val bar = Foo("npe")
}

new System2  // boom!!

Now I use both bar and global very heavily, and therefore I don't want to pay a lazy-val tax just because Scala (2.9.2) doesn't get the initialisation right. What to do?

ic3b3rg
  • 14,629
  • 4
  • 30
  • 53
0__
  • 66,707
  • 21
  • 171
  • 266
  • Actually, it was possible in my concrete case, to add `bar` as constructor argument: `class System3( val bar: Foo ) extends Confluent with Mixin; new System3( Foo( ":-)" ))`—but I'm still interested how to solve this if I hadn't had the possibility of the constructor arg. – 0__ Sep 28 '12 at 21:12

1 Answers1

11

You can use an early initializer:

class System1 extends {
  val bar = Foo("npe")
} with Mixin with Confluent {
  // ...
}

scala> new System1
res3: System1 = System1@1d0bfedd
Community
  • 1
  • 1
kiritsuku
  • 52,967
  • 18
  • 114
  • 136
  • 3
    Wow, can't believe after >4 years of Scala I'm still encountering new things! – 0__ Sep 28 '12 at 21:51