0

Say I do the following:

trait A {
    val i: Int
    override def toString = s"A($i)"
}

case class B(i: Int, j: Int) extends A

println(B(2, 3))

This will give me the output:

A(2)

Is there a way I can make B.toString revert to the default toString for a case class without me having to explicitly write:

override def toString = s"B($i,$j)"
user79074
  • 4,937
  • 5
  • 29
  • 57
  • See https://stackoverflow.com/questions/27465951/how-to-avoid-scalas-case-class-default-tostring-function-being-overridden – sachav Jan 20 '20 at 12:49

2 Answers2

2

It used to be

override def toString = scala.runtime.ScalaRunTime._toString(this)

but that object was removed in 2.12 EDIT: it was only removed from ScalaDoc, but still exists.

To avoid relying on ScalaRunTime._toString, you can define it yourself:

def _toString(x: Product): String =
  x.productIterator.mkString(x.productPrefix + "(", ",", ")")
Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • Thanks! It just can't be found in Scaladoc for some reason https://www.scala-lang.org/api/2.12.0/scala/index.html?search=scalaruntime – Alexey Romanov Jan 20 '20 at 13:00
  • 2
    The reason it's not in the ScalaDoc is explained in the code: `The object ScalaRunTime provides support methods required by the scala runtime. All these methods should be considered outside the API and subject to change or removal without notice.` – sachav Jan 20 '20 at 13:08
2

Perhaps

trait A {
  val i: Int
  override def toString = this match {
    case p: Product => scala.runtime.ScalaRunTime._toString(p)
    case _ => s"A($i)"
  }
}

case class B(i: Int, j: Int) extends A

class Foo extends A {
  override val i = 42
}

B(2, 3)
new Foo

which outputs

res0: B = B(2,3)
res1: Foo = A(42)
Mario Galic
  • 47,285
  • 6
  • 56
  • 98