Scala case class has a default toString function. But when this case class extends a trait with an existing toString() function, it will be rendered useless. How can I prevent this situation?
            Asked
            
        
        
            Active
            
        
            Viewed 1.2k times
        
    15
            
            
        - 
                    There is a similar question at: http://stackoverflow.com/questions/20998866/scala-prevent-mixing-methods – nitishagar Dec 14 '14 at 03:25
3 Answers
28
            OK here is the easist answer:
override def toString = ScalaRunTime._toString(this)
end of story:)
 
    
    
        Sebastien Lorber
        
- 89,644
- 67
- 288
- 419
 
    
    
        tribbloid
        
- 4,026
- 14
- 64
- 103
- 
                    
- 
                    2noob question: That gave me errors for several reasons; I got this to work: `override def toString() = ScalaRunTime._toString(this)` (I had to add parens after `toString`). Moreover, I had to have my particular class explicitly `extend Product`. Any way to avoid this? (Also, I used `import scala.runtime.ScalaRunTime` to avoid fully qualifying the name.) – not-just-yeti Feb 23 '17 at 12:48
- 
                    3@not-just-yeti declaring as case class is equivalent to extend Product. Other parts are related to scala shortcuts in different versions and not important. – tribbloid Mar 03 '17 at 22:02
9
            
            
        Here's a workaround I think may work, it may be too much ceremony, you decide.  It involves a trait.
trait StandardToString { this:Product =>
  override def toString = productPrefix + productIterator.mkString("(", ",", ")")
}
Now trying it with some samples:
trait Human {
   override def toString() = "Human"
}
case class European(firstName:String) extends Human
and running it with the trait:
scala> new European("Falco") with StandardToString
res0: European with StandardToString = European(Falco)
of course with the trait you are left with
scala> new European("Adele")
res1: European = Human
 
    
    
        Daniel Hinojosa
        
- 972
- 5
- 9
1
            
            
        It's more precise to say that the case class toString is not generated, rather than that it is overridden.
This isn't much of an answer or workaround.
scala> trait X { override def toString = "X" }
defined trait X
scala> case class Y(i: Int) extends X
defined class Y
scala> Y(42)
res0: Y = X
scala> case class Y(i: Int)
defined class Y
scala> class Z(x: Int) extends Y(x) with X { override def toString = super[Y].toString }
defined class Z
scala> new Z(42)
res1: Z = Y(42)
You can't do that with a trait:
scala> trait R extends Y { override def toString = super[Y].toString }
<console>:9: error: Implementation restriction: traits may not select fields or methods from super[C] where C is a class
       trait R extends Y { override def toString = super[Y].toString }
                                                   ^
 
    
    
        som-snytt
        
- 39,429
- 2
- 47
- 129
