Un visitante es realmente un foreach
sin el beneficio de las funciones, así que hagamos un foreach
. El método es estático, sino que toma como primer argumento una Path
, por lo que vamos a enriquecer Path
con un método foreach
, que se realiza con algo como esto:
import java.nio.file._
import java.nio.file.attribute.BasicFileAttributes
implicit def fromNioPath(path: Path): TraverseFiles = new TraversePath(path)
Y todo lo demás está dentro de la clase TraversePath
, que parece algo como esto:
class TraversePath(path: Path) {
def foreach(f: (Path, BasicFileAttributes) => Unit) {
// ...
}
}
esto es suficiente para que usted escriba esto:
ProjectHome foreach ((file, _) => if (!file.toString.contains(".svn")) println(File))
Por supuesto, en realidad no hacer nada, así que vamos a conseguir que haga algo:
class TraversePath(path: Path) {
def foreach(f: (Path, BasicFileAttributes) => Unit) {
class Visitor extends SimpleFileVisitor[Path] {
override def visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult = try {
f(file, attrs)
FileVisitResult.CONTINUE
} catch {
case _ => FileVisitResult.TERMINATE
}
}
Files.walkFileTree(path, new Visitor)
}
}
Allí, ahora que la línea va a hacer lo mismo que hizo su código! Sin embargo, podemos mejorarlo aún más. Sucede que foreach
es el único método requerido de Traversable
, por lo que podemos extender esa clase y obtener todos los métodos de una colección de Scala.
El único problema es que una función Traversable.foreach
toma solo un argumento, y aquí estamos tomando dos. Sin embargo, podemos cambiarlo para recibir una tupla. Aquí está el código completo:
import java.nio.file._
import java.nio.file.attribute.BasicFileAttributes
import scala.collection.Traversable
// Make it extend Traversable
class TraversePath(path: Path) extends Traversable[(Path, BasicFileAttributes)] {
// Make foreach receive a function from Tuple2 to Unit
def foreach(f: ((Path, BasicFileAttributes)) => Unit) {
class Visitor extends SimpleFileVisitor[Path] {
override def visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult = try {
// Pass a tuple to f
f(file -> attrs)
FileVisitResult.CONTINUE
} catch {
case _ => FileVisitResult.TERMINATE
}
}
Files.walkFileTree(path, new Visitor)
}
}
ProjectHome foreach {
// use case to seamlessly deconstruct the tuple
case (file, _) => if (!file.toString.contains(".svn")) println(File)
}
de responsabilidad: He probado ninguno de este código, porque no tengo instalado Java 7. Probablemente hay algunos errores.