0

Suppose I have following trait and object:

trait T {
    val x: Int
    println("In Trait", x)
}

object Obj extends T{
    val y: Int = 10
    val x: Int = y
    def run() = {
        println("In Obj", x)
    }
}

Obj.run()
// (In Trait,0)
// (In Obj,10)

Can I have the value of x from trait T be the same as the value of x in object Obj? In other words, my expected output should be:

// (In Trait,10)
// (In Obj,10)

Assume that value of y is known only at runtime.

Mario Galic
  • 47,285
  • 6
  • 56
  • 98
Vlad
  • 8,225
  • 5
  • 33
  • 45
  • 3
    Does this answer your question? [In Scala, what is an "early initializer"?](https://stackoverflow.com/questions/4712468/in-scala-what-is-an-early-initializer) – Suma Aug 12 '20 at 12:27
  • 1
    This feels like an XY problem. Why do you want to call code in the trait initialiser that accesses values from a subclass? – Tim Aug 12 '20 at 13:45

2 Answers2

0

The reason that you are seeing (In Trait, 0) is that you are printing the value during the initialisation of the trait and before the value has been assigned by the object. In this case you get the default, 0. If it was an object you would get a null pointer exception.

Once the object is initialised, the value of x is the same in both the object and the trait.

Tim
  • 26,753
  • 2
  • 16
  • 29
  • Thanks for answering! It doesn't answer my question though. I have a logic that is implemented in trait (which is simulated by `println(x)` in my question) and I need to use that value of `x` from object in trait during initialisation stage. Can this be done? – Vlad Aug 12 '20 at 12:26
  • 1
    I think what you want is early initialization. Check the link to the question I have suggested this is a duplicate of, and if it answers your question, you can mark it as such. – Suma Aug 12 '20 at 12:30
  • The problem is that there is no way to force the user of the trait to use early initialisation, so this feels like bad design. If we knew why the OP wanted to do this there is probably a better solution. – Tim Aug 12 '20 at 13:47
0

Try early initializer

trait T {
  val x: Int
  println("In Trait", x)
}

object Obj extends {
  val y: Int = 10
  override val x: Int = y
} with T {
  def run() = {
    println("In Obj", x)
  }
}

Obj.run()
// (In Trait,10)
// (In Obj,10)
Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66