saulspatz
saulspatz

Reputation: 5281

Closures in Scala

I'm trying to learn Scala and I can't understand this example. In listing 9.1 of Programming in Scala, by Odersky et. al., the authors produce this code

object FileMatcher {
  private def filesHere = (new java.io.File(".")).listFiles
  private def filesMatching(matcher: String => Boolean) =
    for (file <- filesHere; if matcher(file.getName))
      yield file
  def filesEnding(query: String) =
    filesMatching(_.endsWith(query))
  def filesContaining(query: String) =
    filesMatching(_.contains(query))
  def filesRegex(query: String) =
    filesMatching(_.matches(query))
}

They give a scenario where you are writing a FileMatcher object to be used by client code written by others, and this code is the result of a couple of refactorings.

I understand that query is a free variable, but I don't understand how the caller is supposed to make use of it. Since Scala is, if I understand correctly, lexically scoped, and this is an object definition, the client can't define query in a lexically enclosing scope, so where is query to come from?

Can you give me an example of how a client is supposed to call filesEnding to find all files ending in ".txt" for example?

Upvotes: 2

Views: 655

Answers (1)

Daniel C. Sobral
Daniel C. Sobral

Reputation: 297295

Try it.

scala> object FileMatcher {
     |   private def filesHere = (new java.io.File(".")).listFiles
     |   private def filesMatching(matcher: String => Boolean) =
     |     for (file <- filesHere; if matcher(file.getName))
     |       yield file
     |   def filesEnding(query: String) =
     |     filesMatching(_.endsWith(query))
     |   def filesContaining(query: String) =
     |     filesMatching(_.contains(query))
     |   def filesRegex(query: String) =
     |     filesMatching(_.matches(query))
     | }
defined module FileMatcher

scala> FileMatcher filesEnding "xml"
res7: Array[java.io.File] = Array(./build.examples.xml, ./build.xml, ./build.detach.xml)

scala> FileMatcher filesContaining "example"
res8: Array[java.io.File] = Array(./build.examples.xml)

If you have further questions, please add them.

Upvotes: 6

Related Questions