1

I'm trying ot define a val inside a Class' constructor but I'm not getting it to work. It's a fairly intense computation so I don't want to run it twice. I saw this the following link but when I try to do that with this code it doesnt work (i get "application does not take parameters" still): How do you define a local var/val in the primary constructor in Scala?

class MyModel(
  val foo: String,
  val bar: String,
  val baz: String,
) extends db.BaseModel {
  def this() = this(
    foo = "",
    bar = "",
    baz = ""
  )

  def this(
    foo: SomeModel,
    bar: String,
    baz: String,
  ) = {
    this(
      someModel.id,
      doSomeComplexComputation(),
      doSomeComplexComputation(),
    )
  }

I'd like to have something like:

class MyModel(
  val foo: String,
  val bar: String,
  val baz: String,
) extends db.BaseModel {
  def this() = this(
    foo = "",
    bar = "",
    baz = ""
  )

  def this(
    foo: SomeModel,
    bar: String,
    baz: String,
  ) = {
    val complexCalcSaved = doSomeComplexComputation()
    this(
      someModel.id,
      complexCalcSaved,
      complexCalcSaved,
    )
  }

But as I mentioned above I get "application does not take parameters". How do I go about this?

Oscar Godson
  • 31,662
  • 41
  • 121
  • 201

2 Answers2

4

I would recommend creating constructors in the companion object. In your case, such an implementation can work:

class MyModel(val foo: String, val bar: String, val baz: String) extends db.BaseModel

object MyModel {

//empty constructor
def apply(): MyModel = new MyModel("", "", "")

//another constructor
def apply(foo: SomeModel, bar: String, baz: String): MyModel = new MyModel(foo.id, doSomeComputation(bar), doSomeComputation(baz))
}

Now you can call the constructors:

//create a MyModel object with empty constructor
MyModel() 

//create a MyModel object with the second constructor
MyModel(someModel, "string1", "string2")
fcat
  • 1,251
  • 8
  • 18
  • This look like it works! Thank you for mentioning the usage as well. I probably would have tripped on that a few times :) – Oscar Godson Sep 27 '17 at 20:17
  • No problem mate. I struggled for a while to understand in the beginning, that's why I explained the usage as well :) – fcat Sep 28 '17 at 09:33
1

I would write this with companion object and apply method:

  class MyModel(
                 val foo: String,
                 val bar: String,
                 val baz: String,
               ) extends db.BaseModel 

  object MyModel {
    def apply(): MyModel = new MyModel("", "", "")
    def apply(foo: SomeModel,
              bar: String,
              baz: String): MyModel = {
      val complexCalcSaved = doSomeComplexComputation()
      new MyModel(someModel.id, complexCalcSaved, complexCalcSaved)
    }
  }
Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66