How to Use Splat and Optional Arguments in Ruby Methods
This guide explains how to use the splat and optional argument types with Ruby methods to give flexible interfaces to programs
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

This guide explains how to use the splat and optional argument types with Ruby methods to give flexible interfaces to programs. So far we've covered traditional, named and default arguments. However Ruby isn't done yet. When it comes to passing data to methods Ruby gives a few more key tools that we can use:

  • Traditional splat arguments
  • Keyword based splat arguments
  • Optional arguments

Traditional Splat Arguments

One of my favorite components on Ruby is how explicit many of its methods are, and splat may be one of my favorites. The splat argument allows developers to pass an array of values into a method. Imagine that we are building a program that manages a baseball team. If we had a roster method that printed out all of the player names it would be messy to try to pass all of the names into the method one by one.

For example this is what it would look like if we simply tried to pass three players into the method manually:

def roster player1, player2, player3
  puts player1
  puts player2
  puts player3
end

roster 'Altuve', 'Gattis', 'Springer'

Technically this code would work. However this is a trivial example, a baseball team keeps 40 players on their roster. I wouldn't even be able to fit the method on a single page if I tried passing in all of the players one by one. Thankfully this is where Ruby's splat tool comes into play.

We can refactor our code to look like this:

def roster *players
  puts players
end

roster 'Altuve', 'Gattis', 'Springer'

The syntax for using the splat operator is to put an asterisk in front of the argument name. From that point you can pass one or any number of values to the method and they'll all be stored in the splat argument.

large

Once inside the method you can treat the argument like an array (I know we haven't covered arrays yet, for right now think about them as a collection of objects).

This is a powerful tool because there are plenty of times when you're going to need to pass values to a method but you won't always know the exact number of items. In cases like this splat is very handy.

Keyword based splat arguments

In addition to regular splat arguments that are essentially flexible containers for arguments, Ruby also allows for keyword based splat arguments. You can think about this tool as a cross between splat and keyword arguments.

Extending our baseball roster method. Let's imagine that we need to give it the ability to print out the full list of players and positions. By leveraging keyword based splat arguments we can accomplish this feature. The code for this feature is below:

def roster **players_with_positions
  players_with_positions.each do |player, position|
    puts "Player: #{player}"
    puts "Position: #{position}"
    puts "\n"
  end
end

data = {
  "Altuve": "2nd Base",
  "Alex Bregman": "3rd Base",
  "Evan Gattis": "Catcher",
  "George Springer": "OF"
}

roster data

Here we're storing our players and positions in a Ruby hash data structure called data. We'll cover hashes later on in the course. For right know just know that hashes let you store key/value based data.

large

In our roster method we're declaring that we're using the keyword based splat operator by putting the double asterisk in front of the argument. Inside of the method we're looping over the data and printing out the respective player and position values. Notice how we can place block arguments inside the pipes (player and position in this case) that we can call with each loop iteration.

This is a great technique to use if you're working with dynamic data that has a specific key/value based kind of structure. This is common when using database queries.

Optional Arguments

Last on our list of method arguments is the ability to pass optional arguments to a method. There are a number of times when you want flexibility with what types of data you pass to methods and that's where optional arguments can come in handy.

Let's imagine that we're creating an invoice method. Our implementation needs to be flexible because some customers provide different data than others. We can accommodate this type of behavior by using code like this:

def invoice options={}
  puts options[:company]
  puts options[:total]
  puts options[:something_else]
end

invoice company: "Google", total: 123, state: "AZ"

When we run this program you can see some interesting behavior. We're using the options hash in our method declaration. The term options is not required, you could use any word, but using options is considered a standard term to use.

large

From this point we can syntax such as options[:company] to grab the parameters that we want to use. There is a clear mapping between the name we call inside the method to the named argument we pass when we call the method. Also of note (and warning) is that this type of tool can cause silent bugs in your program. Do you notice how I attempted to print out options[:something_else] and I also passed an additional argument of state: "AZ" into the program? However these items did not throw an error. This means you need to be careful when you use optional arguments because they won't fail, they simply won't do anything.