Saptamus Prime
Saptamus Prime

Reputation: 228

How do I initialize object vals with values known only at runtime?

Let's say I'm trying to write a simple Tic-Tac-Toe game. It has an M x N field. The game has only one field, so it probably should be represented with a singleton object. Like this:

object Field {
    val height : Int = 20
    val width : Int = 15
    ...
}

But I don't want to hardcode the height and width, so it would be nice if those could be passed to the object at runtime, via a constructor or something. But objects cannot have constructors.

Well, I could change height and width to be vars, and not vals and introduce a new method

def reconfigure (h:Int, w:Int) = {
    height = h
    width = w
}

and call it at the begining of the game. But it's not elegant as well.

So, is there a neat way of doing this - i.e. having object vals initialized with values not known before runtime?

Upvotes: 15

Views: 19459

Answers (3)

missingfaktor
missingfaktor

Reputation: 92046

Why not use a class and initialize one instance in main?

case class Field(width: Int, height: Int) {
  //...
}

object Main {
  def main(args: Array[String]): Unit = {
    val field = Field(30, 25)
  }
}

Upvotes: 14

Neil Essy
Neil Essy

Reputation: 3607

You could employ the use of lazy vals. This may make things more complex any you still need to use a var.

case class Config( height: Int, width: Int )
object Field {
  val defaultConfig = Config( 20, 15 )
  var config: Option[Config] = None
  def getConfig = config.getOrElse( defaultConfig )
  lazy val height = getConfig.height
  lazy val width = getConfig.width
}
object Main extends App {
  Field.config = Some( Config( 30, 25 ) )
}

Upvotes: 15

Paul Butcher
Paul Butcher

Reputation: 10852

One option is lazy vals:

object Field {
  lazy val height = // code to find height
  lazy val width = // code to find width
}

The val will be initialised the first time it's used, so as long as you don't use them until you have all the information you need to initialise them, you should be good.

Upvotes: 3

Related Questions