scalatraits

Take default value if not present


Have trait like below

trait MyTrait
{
    val country: String,
    val state: String,
    val commune: String = "nothing"

}

Now implementing MyTrait

case class ImplementTrait(
               country:String,
               state: String,
               //commune, how to provide commune's default value if commune is not provided while initialising  ImplementTrait
) extends MyTrait

For example

ImplementTrait(country, state), should work and because it will take commune default value

ImplementTrait(country, state, commune), should also work and because commune value is present now

any suggestions ?


Solution

  • I don't think there's something automatic that you can do easily, but you might want to consider something like the following:

    object MyTrait {
      val DefaultCommune = "nothing"
    }
    
    trait MyTrait {
      def country: String
      def state: String
      def commune: String
    }
    
    final case class ImplementTrait(
        country: String,
        state: String,
        commune: String = MyTrait.DefaultCommune,
    ) extends MyTrait
    
    assert(ImplementTrait("Germany", "Bayern").commune == "nothing")
    assert(ImplementTrait("Mexico", "Yucatan", "Merida").commune == "Merida")
    

    You can play around with this code here on Scastie.

    Notice a couple of changes I made to your original suggestion, as further feedback:

    1. No vals in traits: you know best of course for the use case you want to cover, but in general vals in trait tend to be discouraged as the order in which you inherit traits might affect the initialization of the class (see here for more details)
    2. final case class: while you cannot inherit directly between case classes, you can have a normal class inherit from a case class -- this is very unlikely something you want and might affect value semantics, which is why it's usually recommended to make all case classes final (see here for more details)