Best approach to reading Scala DSL code?
On Squeryl getting started page there is a Scala开发者_如何学编程 code sample:
import sbt._
class Project(info: ProjectInfo) extends DefaultProject(info) {
val squeryl = "org.squeryl" % "squeryl_2.8.1" % "0.9.4-RC3"
}
I'm puzzled because % is not a method defined in RichString or String classes. My best guess is that it's defined elsewhere and called as an implicit conversion.
What would be the best approach to read and understand such code in Scala?
It can only come from import sbt._
or from DefaultProject
. Since sbt
is not a package object, it must come from DefaultProject
.
This is because implicits must be defined or imported into the scope, and you can only import them from objects (either object
objects, or instances of classes). The exception being implicits defined on companion objects of the source or target (when known) type, neither of which apply as you had already checked.
That is a bit moot, though. The reason why the new Scaladoc was creates is precisely to handle such problems.
Take, for instance, a Scala parser:
import scala.util.parsing.combinator.JavaTokenParsers
object T extends JavaTokenParsers {
def myparser = "\\w+".r ~ "\\d+".r
}
The method ~
is not defined on Regex
, so we search for it. Check the latest scaladoc here to try out the explanation below.
Simplest way: click on #
in the upper left corner, to get a list of methods starting with a symbol. Scroll down to ~
, and see: BigInt OnceParser Parser Parsers. From here on, use trial, error and intuition.
Methodic way: type JavaTokenParsers
on the search box to quickly find the class, then select it. On the list of methods, find an implicit
from Regex
to something else. There's only one, which takes to Parser
. Click on Parser
to verify.
You may want to click on implicit def regex
, the method doing the conversion, to see where it is defined: RegexParsers
. The docs to JavaTokenParsers
show that method's definition even though it is not defined or overridden in that class.
This is of particular importance, because if you check SBT API Documentation on DefaultProject
, you'll stumble upon the fact that it defines no methods itself, and only provides the name of the methods on its 40 (if I counted it right) ancestor traits and classes. It can take a while until you click on ManagedProject
to find it has implicit conversions from String
to both GroupID
and RepositoryName
, the former defining %
and %%
, while the later defines at
.
IntelliJ's Scala plugin can normally find them for you, so you can use ^b to go right to it. Beyond that, it's a search through the documentation, starting with what you've imported.
It's an implicit conversion alright!
As with all implicits, if it isn't predefined in the core library, then the best place to start looking is your imports & superclass.
In the given example, this is pretty obviously something from SBT, so you can find it with a quick search on google code
精彩评论