S12000
S12000

Reputation: 3396

Scala class: avoid parameters while creating new instance

Suppose I have 2 files.

Briefly myMainApplication.scala contains

val name = "blah"
val age= 45

Briefly my class myMainApplication.scala should print out the name and the age by creating a new printInfos instance. However I should not add any parameters while creating the instance.

What I would like to AVOID:

Inside printInfos.scala

    class printInfos(val myName: String, 
                     val myAge: Int
                     val myLoc: String
                     val myNPP: Double
                     val myCountry: String
                     val myProvice: String
                     val myNPAP: String) {

    def printInfos() = {
        println("Your method printInfos print out" + myName + myAge + myLoc + myNPP + myCountry + myProvice + myNPAP)
    }

}

Inside myMainApplication.scala

val name = "blah"
val age= 45
val loc = "blah"
val npp = 45.5
val country = "germany"
val province = "bayern"
val npap = "blaha"
// want to avoid to enter so many params
val printInfoInstance = new printInfos(name, age, loc, npp, country, province, npap)
printInfoInstance.printInfos()

I would like to get something similar:

Inside printInfos.scala

    class printInfos() {

       var myName: String  = 0
       var myAge: Int  = 0
       var myLoc: String  = 0
       var myNPP: Double  = 0
       var myCountry: String  = 0
       var myProvice: String  = 0
       var myNPAP: String  = 0

    def printInfos() = {
        println("Your method printInfos print out" + myName + myAge + myLoc + myNPP + myCountry + myProvice + myNPAP)
    }

}

Inside myMainApplication.scala

// want to create new instance with no params at begining
val printInfoInstance = new printInfos()

val name = "blah"
printInfoInstance.myName() = name
val age= 45
printInfoInstance.myAge() = age
val loc = "blah"
printInfoInstance.myLoc() = loc
val npp = 45.5
printInfoInstance.myNPP() = npp
val country = "germany"
printInfoInstance.myCountry() = country
val province = "bayern"
printInfoInstance.myProvice() = province
val npap = "blaha"
printInfoInstance.myNPAP() = npap

printInfoInstance.printInfos

Looking for improvements

Would it be possible to get something similar to the second proposal but avoiding to use var ? However, the final aim is still to avoid adding a lot of parameters when creating a new intance.

Upvotes: 0

Views: 149

Answers (3)

Alvaro Carrasco
Alvaro Carrasco

Reputation: 6172

It is a benefit of the type system to be able to require all the parameters needed to create a valid instance of a class.

If you want to avoid the verbosity of passing all the parameters every time, you can provide default values for them (only a good idea if they are truly optional, as you really want to avoid invalid intermediate states).

// assuming it doesn't make sense to instantiate without 
// a few required parameters
case class InfoPrinter (
  name: String,             // required 
  age: Int,                 // required
  loc: String = "",
  NPP: Double = 0,
  country: String = "",
  province: String = "",
  NPAP: String = ""
) {
  def printInfos = 
    println(s"Your method printInfos print out $name $age $loc $NPP $country $province $NPAP")

}

You can then use it like this:

// named params or positionally
InfoPrinter("blah", 45, country="germany", province="bayern").printInfos

Any parameters with default values can be omitted.

Upvotes: 1

phantomastray
phantomastray

Reputation: 449

In addition to what @longshorej has mentioned, provided you have a case class defined. you can instantiate without the new keyword: printInfos("name","age","loc","npp","country","province","npap") would create a new instance.

For the printing part I'd suggest overriding toString so that it aligns well with standard nomenclature.

Upvotes: 1

longshorej
longshorej

Reputation: 381

I'd suggest you use scala's case classes for this. It provides a copy method that allows you to create a new instance with the changed parameters. This keeps everything immutable. Note that you don't have to update all of the parameters - you could just do one at a time.

case class printInfos(myName: String = "",
                      myAge: Int = 0,
                      myLoc: String = "",
                      myNPP: Double = 0,
                      myCountry: String = "",
                      myProvince: String = "",
                      myNPAP: String = "") {
  def printInfos() = {
    println("Your method printInfos print out" + myName + myAge + myLoc + myNPP + myCountry + myProvince + myNPAP)
  }
}

val printInfoInstance = new printInfos()

val name = "blah"
val age= 45
val loc = "blah"
val npp = 45.5
val country = "germany"
val province = "bayern"
val npap = "blaha"

val newInstance = printInfoInstance.copy(
  myName = name,
  myAge = age,
  myLoc = loc,
  myNPP = npp,
  myCountry = country,
  myProvince = province,
  myNPAP = npap
)

newInstance.printInfos()

Upvotes: 3

Related Questions