Ruby’s Secret Power: Flexible Argument Processing

When you think of a method, how do you envision its parameters? Depending on whom you ask, you might get a lot of different answers. Some folks might think of something vaguely mathematical, such as f(x,y,z), where each argument is necessary, and the order in which they are provided is significant. Others might think of methods as manipulating configuration data, where keyword-like parameters seem natural, e.g., create_person( first_name: "Joe", last_name: "Frasier"). You might also contemplate mixing the two together, or dreaming up something else entirely.

Ruby provides a great deal of flexibility in how it handles method arguments, which might lead to some confusion. However, this is also a key part of building beautiful APIs in Ruby. The following examples give just a small taste of the kind of diversity you can expect in Ruby:

# Standard ordinal arguments
def distance(x1,y1,x2,y2)
  Math.hypot(x2 - x1, y2 - y1)
end

# Ordinal arguments, with an optional argument
def load_file(name,mode="rb")
  File.open(name,mode)
end

# Pseudo-keyword arguments
def story(options)
  "#{options[:person]} went to town, riding on a #{options[:animal]}"
end

# Treating arguments as an Array
def distance2(*points)
  distance(*points.flatten)
end

Invoking these methods shows how they look in action:

>> distance(3,3,4,5) => 2.23606797749979 >> load_file "foo.jpg" => #<File:foo.jpg> >> load_file "foo.jpg", "r" => #<File:foo.jpg> >> load_file "foo.jpg", "kitten" ArgumentError: ...

Get Ruby Best Practices now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.