tags:

views:

149

answers:

1

If i am reading each line of a file like the following

file.eachLine {line->
println line
}

is it possible to read the NEXT line inside the closure.

for example

file.eachLine {line ->
//print next line as well if current line contains 'hooray'
if (line.find(/hooray/)!=null)
{
   println "current line: ${line}"
   println "next line: ${line->next}" //this is just my syntax...
}
}
+1  A: 

That's not directly supported by the closure, but it's easy enough to achieve the same logic if you change things around slightly:

// test script:
def f = new File("test.txt")
def currentLine
f.eachLine { nextLine ->
    if (currentLine) {
        if (currentLine.find(/hooray/)) {
            println "current line: ${currentLine}"
            println "next line: ${nextLine}"
        }    
    }    
    currentLine = nextLine
}


// test.txt contents:
first line
second line
third line
fourth line
fifth hooray line 
sixth line
seventh line

Edit:

If you're looking for the encapsulation that Chili commented on below, you could always define your own method on File:

File.metaClass.eachLineWithNextLinePeek = { closure ->
    def currentLine
    delegate.eachLine { nextLine ->
        if (currentLine) {
            closure(currentLine, nextLine) 
        }
        currentLine = nextLine
    }
}

def f = new File("test.txt")
f.eachLineWithNextLinePeek { currentLine, nextLine ->
    if (currentLine.find(/hooray/)) {
        println "current line: ${currentLine}"
        println "next line: ${nextLine}"
     }
}
Ted Naleid
the currentLine var can also be closed over a new closure *inside* the eachLine closure - that way, you dont expose the currentLine variable outside (encapsulation etc).
Chii