Sonntag, 4. Januar 2015

Splat in Ruby method parameters!

Some methods have to deal with collections. The method definition for assigning a collection should not look like:
class Recipe
  def initialize ingredients=[]
    @ingredients = ingredients
  end
end
because sending the message then is as awful as:
Recipe.new ['Banana', 'Chocolate', 'Almonds']
or even worse:
Recipe.new ['Banana']
But the splat (*) operator in Ruby can solve it. The code can be refactored to:
class Recipe
  def initialize *ingredients
    @ingredients = ingredients.flatten.sort
  end

  def ingredients
    @ingredients.join(', ')
  end
end
and sending the message again:
recipe = Recipe.new 'Banana', 'Chocolate', 'Almonds'
recipe.ingredients
=> "Almonds, Banana, Chocolate"
or assigning just one object:
Recipe.new 'Banana'
Even assigning an Array works, because Array#flatten flattens the collection into an one dimensional array:
ingredients = %w(Banana Chocolate Almonds)
recipe = Recipe.new ingredients
=> #<Recipe:0x00000003de66a8 @ingredients=["Almonds", "Banana", "Chocolate"]>
In general the splat (*) operator can be used to split an Array:
one, two, three = *[1, 2, 3]
one
=> 1
two
=> 2
three
=> 3
and to collect an Array:
*numbers = 1, 2, 3
numbers
=> [1, 2, 3]
With the help of the Ruby splat (*) operator method parameters can be variable from zero up to many and handled as an Array internally. No archaic Array assignments anymore. And flatten the collection parameter with Array#flatten increases the flexibility of the API method.
Further articles of interest:

Supported by Ruby 2.1.1