Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A constructor with a parameter in Scala

Tags:

scala

I need only one instance of a class, so I have to use an object instead of a class. I also need to set some initial value chosen by a client, so I need to a constructor for an object, something like this:

object Object1(val initValue: Int){
  //.....
}

I can't use this exact code in Scala. How do I deal with that then?

like image 481
Alan Coromano Avatar asked Jun 03 '13 16:06

Alan Coromano


2 Answers

You have a couple of choices:

  1. Make it a class, have the client construct it, give the value in the parameter
    Pro: Preserves immutability
    Con: Having only a single instance might be hard to manage

  2. Add a variable for the param to the object, add a setter.
    Pro: You still have a singleton
    Con: There is mutable state now

  3. Implement a multiton
    Pro: Gives you (apparent) immutability and singleton (per param)
    Con: More code to implement

You could implement a multiton like this in scala:

class Object1 private (val initValue: Int) {
  // ...
}

object Object1 {
  val insts = mutable.Map.empty[Int, Object1]

  def apply(initV: Int) =
    insts.getOrElseUpdate(initV, new Object1(initV))
}

UPDATE You could also turn this into a "singleton with parameter":

object Object1 {
  var inst: Option[(Int, Object1)] = None

  def apply(initV: Int) = inst match {
    case Some((`initV`, i)) => i
    case Some(_) =>
      sys.error("Object1 already instantiated with different param")
    case None =>
      val i = new Object1(initV)
      inst = Some((initV, i))
      i
  }
}
like image 70
gzm0 Avatar answered Sep 24 '22 22:09

gzm0


The object isn't created until you reference it, so you could do something like the following:

object Test1 extends App {
  var x = Console.readLine
  println(Object1.initVal)
}

object Object1 {
  val initVal:String = Test1.x
}
like image 5
tsjnsn Avatar answered Sep 22 '22 22:09

tsjnsn