Search code examples
rubyverbosity

Is there a shorthand for Ruby Blocks?


I find myself annoyed with the following verbose writing in Ruby:

polys.each { |poly| poly.edges.each {|edge| draw edge.start, edge.end } }

(polys is an Array of Polygons, edges is a method of Polygon returning an Array of Edges)

Ideally I would like to shorten this to something like this:

polys.each.edges.each { draw _.start, _.end }

More specifically I would like to know:

  • How could we write a method_missing hack as with the first each? (Upon being called with a missing method, the enumerator could call this method on each item returned from the enumeration)
  • Is there a way to get rid of the |x| using any symbol or default name?

Solution

  • No. Closest you can do would be:

    polys.flat_map(&:edges).each { |_| draw _.start, _.end }
    

    flat_map will convert an array in another array and flatten it to a single dimension array. If the inside of a block is calling a single method with no parameters, you can use the &:edges shortcut.

    This being said, I would probably keep it closer to your initial proposal, as it's more readable:

    polys.each do |poly| 
      poly.edges.each {|edge| draw edge.start, edge.end }
    end
    

    Remember, you write code once but it's read a lot, so readability trumps terseness.