Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialize a val from a secondary constructor

Tags:

scala

I have the following class representing some amount of money:

class Money(initDollars: Int, initCents: Int){

  require (initDollars >= 0 && initCents >= 0)

  private def this(positive: Boolean, initDollars: Int, initCents: Int) = {
    this(initDollars, initCents)
    //this.positive = positive
  }

  val positive: Boolean = true
  val dollars = initDollars + initCents/100
  val cents = initCents % 100
  private val totalAmount = dollars * 100 + cents

  def unary_- = new Money(!positive, dollars, cents)
}

object Money{
  def apply(initDollars: Int, initCents: Int) = new Money(initDollars, initCents)
}

The amount can also be negative and I want to create it like this:

val am = -Money(1, 20)

So I want to initialize val positive from a secondary constructor, but I can't do it, because it's reassignment to val. I also can't add val in the list of parameters to secondary constructors. Could someone help?

like image 360
Konstantin Milyutin Avatar asked May 26 '13 15:05

Konstantin Milyutin


3 Answers

Do it the other way around.

class Money private (pos: Boolean, initDollars: Int, initCents: Int) {

  require (initDollars >= 0 && initCents >= 0)

  def this(initDollars: Int, initCents: Int) = {
    this(true, initDollars, initCents)
  }

  val positive: Boolean = pos
  val dollars = initDollars + initCents/100
  val cents = initCents % 100
  private val totalAmount = dollars * 100 + cents

  def unary_- = new Money(!positive, dollars, cents)
}
like image 117
n. 1.8e9-where's-my-share m. Avatar answered Oct 12 '22 23:10

n. 1.8e9-where's-my-share m.


I think in order to achieve what you want, you have to do the following structural modification:

class Money(initDollars: Int, initCents: Int, positive: Boolean)

That way, you can then write a constructor that has less parameters without a problem (e.g. omitting "positive"). Doing it the other way around will be hard in Scala, if you want to stick to immutable values.

If you have the following declaration in your class body:

val positive: Boolean = true

You won't be able to change positive anymore, no way around it :)

like image 41
fresskoma Avatar answered Oct 12 '22 23:10

fresskoma


Switch to one constructor, add positive to the end and give it a default value of true like this:

positive:Boolean = true

This way if defaults to true if not supplied. Then do the same for your apply function and invoke the 3 field constructor in apply.

like image 31
cmbaxter Avatar answered Oct 12 '22 23:10

cmbaxter