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