Splatting in iterators

Published on .

I can’t even count how many times I’ve seen code like this:

arr = [[:name, 'Name'], [:location, 'Location']]
arr.each do |el|
  attr = el[0]
  label = el[1]
  p attr, label
end

Ruby can automatically split arrays in iterators by simply giving more than 1 parameter to a block:

arr = [[:name, 'Name'], [:location, 'Location']]
arr.each do |attr, label|
  p attr, label # Does the same thing as code above
end

It works with any interator method, not just each:

arr = [[:name, 'Name'], [:location, 'Location']]
arr.select do |attr, label|
  attr == :name
end

In fact ruby even allows you to nest splitting:

arr = [[:name, ['Name', 1]], [:location, ['Location', 2]]]
arr.each do |attr, (label, count)|
  p attr, label, count
end

This is especially useful with Array#zip method:

arr1 = [:name, :location]
arr2 = ['Name', 'Location']
arr1.zip(arr2).each do |attr, label|
  p attr, label
end