Search code examples
scalainheritancetostringcase-class

toString method for inherited case class in Scala


I am facing some inconsistency in calling toString method for case-classes in Scala. The first code sample:

case class Person(name: String, age: Int)
val jim = Person("jim", 42)
println(jim)

output: Person(jim,42)

For the next code sample I used a case class that extends Exception:

case class JimOverslept(msg: String) extends Exception
try {
  throw JimOverslept(msg = "went to bed late")
} catch {
  case e: JimOverslept => println(e)
}

output: playground.CaseClassOutput$JimOverslept

Actually, I would prefer the output like JimOverslept(went to bed late)

What is the reason the both outputs are so different? And what is the best way to obtain the output looks like desired one (JimOverslept(went to bed late))


Solution

  • According to SLS 5.3.2 Case Classes

    Every case class implicitly overrides some method definitions of class scala.AnyRef unless a definition of the same method is already given in the case class itself or a concrete definition of the same method is given in some base class of the case class different from AnyRef.

    Now toString is already provided by base class in

    case class JimOverslept(msg: String) extends Exception
    

    where Exception extends base Throwable which provides toString definition. Hence try providing an override within the case class itself like so

    case class JimOverslept(msg: String) extends Exception {
      override def toString: String = scala.runtime.ScalaRunTime._toString(this)
    }