Why You Should Be Naming Arguments In Ruby

Today we're discussing how and why you should use named arguments in your Ruby projects.


How do I name arguments?

We will start with Ruby version 1.9 and previous versions to demonstrate the old way of naming arguments for a specific method. The way to name your arguments in these versions is as follows:

# method declaration
def concat_strings(options = {}) do
  return options.fetch(:foo) + options.fetch(:bar)
end

# method invocation
concat_strings({foo: "Hello", bar: " World"})

Notice that the default options hash is empty. This means that no arguments are required and anything passed through the hash is optional.

If you're using Ruby 2.0 or above, you can now take advantage of Keyword Arguments.

The following is a representation of the previous method written with Ruby 2.0+ style keyword arguments. Try to notice the difference from the previous example.

# method declaration
def concat_strings(:foo, :bar) do
  return :foo + :bar
end

# method invocation
concat_strings(foo: "Hello, bar: " World")

Did you notice the difference? The above sample code omits the options hash and uses the symbols foo and bar directly as a baked in way to name your arguments. Pretty nifty eh?

The following would produce the same output:

# method invocation
concat_strings(bar: " World", foo: "Hello)

Naming your arguments allows you to pass arguments to a method in any order you like during the method invocation, since the method is using the arguments' names to ascertain their values rather than the arguments' order.

There's a problem here though, have you guessed it yet? In our first example, our hash of arguments was optional and the default value was an empty hash.

If we tried calling concat_strings in our latest example we would get an error, albeit a helpful one, describing the names of the required arguments that you forgot to use in the method invocation.

To make a keyword argument optional you need to provide it with a default value. Note the following example:

# method declaration
def concat_strings(foo: "foo", bar: "bar") do
  return :foo + :bar
end

This new method declaration accounts for default values for both of our keyword arguments. Now, if we call concat_strings without any arguments the result will get a default value of "foobar". Although it would be unlikely to return a default concatenated string in this use case, it would be easy to add some control flow to handle the missing arguments within the method declaration.

That's it! Now let's get onto the Why...


Why should I do this?

Naming your arguments in Ruby ( whether you're using the latest version or 1.9 and below ) reduces the chance of an unforeseen error during later stages of development, especially when your project's feature requirements have changed scope.

Imagine you wanted to change the order in which your unnamed arguments are referenced in your method declaration.

You would then have to find every single invocation of that method in your entire project and switch the order of the arguments. This creates an unnecessary potential for technical debt that can be avoided by using a simple hash or the newer keyword argument feature.

As you use named arguments you will quickly find that it increases the readability of your code by further defining what is actually going on. Other developers will also appreciate your new habit.