· ruby

Ruby: One method, two parameter types

One interesting thing that I’ve noticed while coding in Ruby is that due to the dynamicness of the language it’s possible to pass values of different types into a given method as parameters.

For example, I’ve recently come across a few examples of methods designed like this:

def calculate_foo_prices(foos)
   ...
   [foos].flatten.each do |foo|
      # do something
   end
end

This allows us to use the method like this:

# foos would come in as an array from the UI
foos = [Foo.new, Foo.new, Foo.new]
calculate_foo_prices(foos)

Or like this:

calculate_foo_prices(Foo.new)

It becomes quite confusing to understand why what is supposedly already a collection is being put inside an array on line 3 of the first example when you first read it.

An alternative would be to pull out a different method for calculating the price of the single Foo:

def calculate_foo_price(foo)
   calculate_foo_prices([foo])
end

And then simplify the original method:

def calculate_foo_prices(foos)
   ...
   foos.each do |foo|
      # do something
   end
end

While writing this I was thinking that another way could be to change the original method to look like this by using the splat operator:

def calculate_foo_prices(*foos)
   ...
   foos.each do |foo|
      # do something
   end
end

Which means that we can use the same method for both situations:

calculate_foo_prices(Foo.new)
# foos would come in as an array from the UI
foos = [Foo.new, Foo.new, Foo.new]
calculate_foo_prices(*foos)

I’m guessing the latter is more idiomatic Ruby or perhaps there’s another way I’m not aware of yet?

  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket