Search code examples
scalafunctional-programmingbigdecimalcase-class

Scala BigDecimal in a case class and forcing a MathContext


I am trying to create a case class that holds a BigDecimal as a value with a certain MathContext (RoundUp, Precision 2). The documentation said BigDecimal.mc is a val, so no simple reassignment. So I came up with two solutions. First this one

case class Test(number: BigDecimal)

object Test {
    def apply(n) = new Test(n, new java.math.MathContext(2))
} 

I didn't like that one because it can be circumnavigated with the new keyword.

case class Test(var number: BigDecimal){
    number = BigDecimal(number.toString, new java.math.MathContext(2))
}

That second one works, but is ugly as hell and creates additional overhead. I am just wondering if I overlook something simple and elegant.


Solution

  • What about making the constructor private and thus forcing everyone to use apply?

    // constructor is private - use apply instead!
    case class MyBigDecimal private(number: BigDecimal)
    
    object MyBigDecimal {
      private val defaultContext = new java.math.MathContext(2)
    
      def apply(number: BigDecimal) = new MyBigDecimal(BigDecimal(number.bigDecimal, defaultContext))
    }
    

    Also your second example could be re-written to be just ugly but not that inefficient:

    case class MyBigDecimalWithVar(var number: BigDecimal) {
      number = BigDecimal(number.bigDecimal, new java.math.MathContext(2))
    }