Thursday, December 16, 2010

Curried closures and static methods

If the same static utility method is called from multiple places in Groovy code, and some of the parameters to the method are always the same, curried closure is a nice way to shorten the syntax. For instance, the following static method retrieves all the entries from a list that match a certain pattern:


class MatchHelper {
    static List getMatches(pattern, list) {
        list.grep(pattern)
    }
}

Method getMatches is then called from several places in the code:

def pattern = ~/^[Tt].*/
...
List cars = ["Murano", "Touareg", "Taurus"]
List matchedCars = MatchHelper.getMatches(pattern, cars)
assert  ["Touareg", "Taurus"] == matchedCars
...
List veggies = ["Tomato", "Broccoli", "Sprout"]
List matchedVeggies = MatchHelper.getMatches(pattern, veggies)
assert ["Tomato"] == matchedVeggies
...
List cities = ["Torino", "Sydney", "Tegucigalpa"]
List matchedCities = MatchHelper.getMatches(pattern, cities)
assert ["Torino", "Tegucigalpa"] == matchedCities

Not only does each code snippet calls MatchHelper.getMatches(), but also ~/^[Tt].*/ is passed as the first parameter each time. Instead the code can be shorted this way:

def getTMatches = MatchHelper.&getMatches.curry(~/^[Tt].*/)
...
List cars = ["Murano", "Touareg", "Taurus"]
List matchedCars = getTMatches(cars)
assert  ["Touareg", "Taurus"] == matchedCars
...
List veggies = ["Tomato", "Broccoli", "Sprout"]
List matchedVeggies = getTMatches(veggies)
assert ["Tomato"] == matchedVeggies
...
List cities = ["Torino", "Sydney", "Tegucigalpa"]
List matchedCities = getTMatches(cities)
assert ["Torino", "Tegucigalpa"] == matchedCities

A little less code and a little more elegance. Typical Groovy.

No comments:

Post a Comment