- Read Tutorial
- Watch Guide Video
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.
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.
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.
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.