I was looking through the Specs2 quickstart guide and quickly came across some syntax I'm not familiar with:
"The 'Hello world' string" should {
// more stuff here
}
Digging into the specs2 source, I see that should
is a method of the class Described(s: String)
. Futhermore, Described
appears to be instantiated somehow (as a method described
?) implicitly right before the class definition:
implicit def described(s: String): Described = new Described(s)
class Described(s: String) {
def should(fs: =>Fragment) = addFragments(s, fs, "should")
}
I don't understand:
"some string" should { ... }
. E.g. a string followed by a method call (naively this only makes sense to me if should
were a method on the String class.I actually just came across this pattern which appears to answer my question: the Pimp my Library pattern that makes use of this implicit conversion pattern which I was unfamiliar with. Leaving open just in case its missing any important insight, and because the article was written by Odersky almost 10 years ago.
Looks like you've answered your own question, but I will post more details.
The "Pimp my Library" name has been replaced with "Enriched Library" (for reasons that probably don't need an explanation, although I confess I chuckled when I first learned of pimping out libraries..)
Implicits in Scala do 3 things:
The implicit extension methods pattern has been more formalized in Scala 2.10; the above Described example in your question can be more succinctly written as an implicit value class:
implicit class Described(s: String) {
def should(fs: =>Fragment) = addFragments(s, fs, "should")
}
I understand the compiler will emit more efficient code for implicit value classes, also, as it can skip the allocation of the wrapper class containing the extension methods. See http://www.blog.project13.pl/index.php/coding/1769/scala-2-10-and-why-you-will-love-implicit-value-classes/