8

In Java, I would do something like

class MyDate extends java.util.Date {
  public String toString() { ... }
}

MyDate date = new MyDate

A little bit clunky. In Scala, is it possible to override toString whilst still using regular java.util.Date instead of MyDate. I have an inkling implicits are involved but would be happy to use any technique

deltanovember
  • 38,665
  • 55
  • 151
  • 236
  • If you want code that doesn't know about you to use the correct `toString`, you'll have to extend `java.util.Date`; having a different pointer in the method table of that object is the only way it's going to produce a different string! – Rex Kerr Aug 04 '11 at 12:41

1 Answers1

17

Implicit conversions can only work if the type being converted does not already have a method with a given signature. As everything has a toString, it is not possible to override this by pimping.

What you might do is use a typeclass (akin to scalaz.Show) which looks like this:

trait Show[-A] {
  def show(a : A): String
}

Then you can use show everywhere instead of toString. Ideally what you want then is to make the Show[Any] instance a very low priority implicit.

implicit val DateShow = new Show[Date] { def show(d : Date) = "whatever" }

trait LowPriorityShows {
  implicit val AnyShow = new Show[Any] { def show(a : Any) = a.toString }
}

P.S. The reason I would not suggest using scalaz.Show is that the return type is List[Char], which is just not practicable for most uses

oxbow_lakes
  • 129,207
  • 53
  • 306
  • 443
  • 1
    For an explanation about controlling the priority of implicits, see Daniel Sobral's writeup: http://stackoverflow.com/questions/5598085/where-does-scala-look-for-implicits – Kipton Barros Aug 04 '11 at 16:24