3

I have found following function calls in several frameworks which appear to me as if the framework extends some base classes. Some examples:

within(500 millis)

or

"Testcase description" in
  { .... }

First example returns a duration object with the duration of 500 milliseconds from akka and second is the definition of a testcase from scalatest.

I would like to know how this behavior is achieved and how it is called.

BenMorel
  • 30,280
  • 40
  • 163
  • 285
Sebastian
  • 45
  • 2

2 Answers2

10

This is done with the "Pimp my library" technique.

To add non existing methods to a class, you define an implicit method that converts objects of that class to objects of a class that has the method:

class Units(i: Int) {
  def millis = i
}

implicit def toUnits(i: Int) = new Units(i)


class Specs(s: String) {
  def in(thunk: => Unit) = thunk
}

implicit def toSpecs(s: String) = new Specs(s)

See also "Where does Scala looks for Implicits?"

Community
  • 1
  • 1
IttayD
  • 25,561
  • 25
  • 109
  • 173
1

If I'm not mistaken, those pieces of code can be desugared as

within(500.millis)

and

"Testcase description".in({ ... })

This should make it easier to see what's going on.

hammar
  • 134,089
  • 17
  • 290
  • 377
  • Yeah, i know but then the class Integer must have a member "millis" or String needs to have "in" which they don't have – Sebastian May 10 '11 at 17:15
  • @Sebastian: My guess is there is some sort of implicit conversion going on, but my Scala-fu isn't up to that level yet, so I'm not sure. – hammar May 10 '11 at 17:17