Search code examples
javascalaclassdebuggingprintln

Can I print a case class param that is passed to class function in Scala?


I am trying to print an object that is passed to a class function in scala.

The case class is written:

config {
...
case class NetConfig(
      domain: NetDomain,
      prodDomain: NetDomain,
      @ConfigName("base_url") baseUrl: BaseUrl,
      @ConfigName("asset.domain") assetDomain: AssetDomain,
      @ConfigName("asset.base_url") assetBaseUrl: AssetBaseUrl,
      @ConfigName("asset.minified") minifiedAssets: Boolean,
      @ConfigName("stage.banner") stageBanner: Boolean,
      @ConfigName("socket.domains") socketDomains: List[String],
      crawlable: Boolean,
      @ConfigName("ratelimit") rateLimit: RateLimit,
      email: EmailAddress
  ) {
    def isProd = domain == prodDomain
  }
...
}

The class function is written:

import ....config.NetConfig
final class CSRFRequestHandler(net: NetConfig) {
...
}

I'd like to see the values of all the members of NetConfig when this handler is called. I tried a few things like:

final class CSRFRequestHandler(net: NetConfig) {
println(NetConfig)
(I just got the word NetConfig)

or

println(NetCConfig.domain)
(got compile error value domain is not a member of object lila.common.config.NetConfig)

or NetConfig.show
(got the word NetConfig)

FYI we are using the Play framework. And I don't know scala sigh. What is the correct way to print all the values of NetConfig?


Solution

  • One of the advantages of case classes is that they provide an out-of-the-box toString tailored to their primary constructor's arguments. For example, this:

      case class Person(name: String, age: Int, birthplace: String)
    

    Among other differences from regular classes you can view this as a normal class with the following overridden toString:

      class Person(val name: String, val age: Int, val birthplace: String) {
    
        // ... other case class methods
    
        override def toString: String =
          s"${getClass.getSimpleName}($name,${age.toString},$birthplace)"
      }
    

    This is intentional so that you can view a String representation of every instance of a Person:

      val p = new Person("Hikaru", 25, "Tokyo")
      println(p) // both will print: Person(Hikaru,25,Tokyo)
    

    Whereas a normal class without the toString overridden would print something like:

    <OuterClassWithFullPath>$Person@<hashCode>
    

    So in your case, since net is already an object of the NetConfig type, which is already a case class, just a simple println(net) should do it.

    EDIT: To avoid confusing the type with the variable, besides the fact that the type comes first, then the variable name (this is intentional so that you can sometimes omit the type, such as: val myNumber = 10), remember the naming convention in Scala is the same as in Java: classes or traits should always be named in upper camel case, whereas values and variable names should be names in lower camel case, unless they are constants.