Closures

Closures (aka Blocks) are essentially blocks of code that can be passed as arguments to a function or method. Unlike method pointers, anonymous classes, and other similar things, closures have the unique ability to be able to see the value of variables in the same scope they were created in. For example, if you declare a variable on one line and a closure on the next, the closure will have visibility of the variable when the closure executes, assuming it is passed into the closure.

Martin Fowler has a great example of this. To pull only certain items out of a collection in Java you’d have to do something like this:

public static List<Item> getItemsWeCareAbout(List<Item> orig) {
  List<Item> toReturn = new ArrayList();
  int val = 230;
  for (Item item : orig) {
    if (item.meetsConditionWeCareAbout(val)) {
      toReturn.add(item);
    }
  }
  return toReturn;
}

However, the same code in Ruby can be done like this:

def items_we_care_about(orig)
  val = 230
  return orig.select { |i| i.meetsConditionWeCareAbout val }
end

The Ruby version utilizes closures in that we can pass a block of code into the select method. The actual closure is the code within the curly braces ({..}). This code simply says that each item ( |i| ) that returns true from the meetsConditionsWeCareAbout method should be included in the return collection. Also note that the variable declared in the method is passed into the closure, meaning that the closure has visibility into the variable each time it is executed, not just when it was defined.


About the author

Jason McDonald

View all posts

1 Comment

  • While not as nice as the language supported closures, commons collections has a closure that can be used with CollectionUtils like so:

    CollectionUtils.forAllDo(orig, closure);

    or, more relevant to your example a predicate that can be used like:

    CollectionUtils.select(orig, predicate);

    Of course, they come with the java baggage too (they are objects that must be instantiated, having to cast if you want to pass in something other than what is defined in the interface, etc.). Hopefully Java will integrate closures into the language someday, they are a great feature.

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.