I am learning Scala (coming from a background of mostly Java). I am trying to wrap my head around the following code:
object Main {
def main(args : Array[String]) {
for (file <- filesEnding(".txt"))
println(file.getName)
}
private val filesHere = (new java.io.File(".")).listFiles
def filesMatching(matcher: String => Boolean) =
for (file <- filesHere; if matcher(file.getName))
yield file
def filesEnding(query: String) = filesMatching(_.endsWith(query))
/* Other matcher functions */
}
In particular I am confused where Scala gets the value for _ in each of the matcher functions. I can see that filesEnding is called with an argument of .txt. That argument is assigned to query. filesEnding then calls filesMatching with an argument consistent with a String => Boolean function. Finally I can see that file.getName is what eventually replaces the _ placeholder.
What I don't get is how Scala knows to put file.getName in place of _. I am having trouble tracing this code in my head and the eclipse debugger isn't much help in this situation. Can somebody walk me through what is happening in this code?
The _ is just a shorthand for making an anonymous function:
_.endsWith(query)
is the same as the anonymous function
fileName => fileName.endsWith(query)
This function is then fed as the argument matcher to filesMatching. Inside that function you can see the call
matcher(file.getName)
This calls the anonymous function with file.getName as the _ argument (which I called fileName in the explicit example).
If you write _.someMethod(someArguments), this desugars to x => x.someMethod(someArguments), so filesMatching(_.endsWith(query)) desugars to filesMatching(x => x.endsWith(query)).
So filesMatching is called with matcher being the function x => x.endsWith(query), i.e. a function which takes one argument x and calls x.endsWith(query) on that argument.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With