1
votes

Stupid question, but none of the examples works for me; classic article "Pimp my Library" is buggy and even the simplest code has problems.

Btw. I assume you have to put conversion method in the object (a lot of snippets omit that part). According to PiS book it seems hanging implicit def is OK, but this gives me error as well.

object Minutes
{
  implicit def toMinutes(x : Int) = new Minutes(x)
}

class Minutes(private val x : Int)
{
  def minutes = x.toString+"m"
}

object MainApp {

  def main(args : Array[String])
  {
     println(5.minutes)
     ...

The error -- "value minutes is not a member of Int".

Question

What am I missing? Scala 2.9.1.

3

3 Answers

9
votes

All you need you to do is bring your implicit conversion into scope where you want to use it, so the compiler can find it...

def main(args : Array[String]) {
   import Minutes._
   println(5.minutes)
}
7
votes

The implicit conversion must be in scope, e.g.

def main(args : Array[String]) {
  import Minutes._
  println(5.minutes)
  ...
}

There are other ways, too, e.g. using package objects.

1
votes

You can get the example in the Pimp my library article to work as follows:

class RichArray[T: Manifest](value: Array[T]) {
  def append(other: Array[T]): Array[T] = {
    val result = new Array[T](value.length + other.length)
    Array.copy(value, 0, result, 0, value.length)
    Array.copy(other, 0, result, value.length, other.length)
    result
  }
}

implicit def enrichArray[T: Manifest](xs: Array[T]) = new RichArray[T](xs)

You need a context bound for T: [T: Manifest] is short for [T](implicit m: Manifest[T]). A Manifest is a way of passing the value of T to the method at runtime, when T is known. Normally the parameterized type information is used by the compiler to ensure type safety at compile time, but is not incorporated into the bytecode because the JVM can't handle it (type erasure). Scala collections changed in version 2.8 so that for performance reasons, Arrays are now not automatically wrapped by compiler magic, hence supplying a manifest for generic operations became necessary.

The other change is the (xs) argument for new RichArray[T]. I think that one's a typo.