The asterisk operator commonly known as splat can be a powerful ally in writing clean and highly functional code. The splat operator has a variety of behaviors depending on where it is used, and in this post I’ll focus on the use of splat in conjunction with methods in Ruby 1.9 and later.
Arbitrary Argument Length in Method Signature
Occasionally, we would like to define a method that will accept an undefined number of argument. Typically, we use an optional Hash
as the last argument, which holds a variety of arguments. However, we can also take advantage of the splat operator by placing it in front of an argument variable name in the method definition. It will cause the argument variable to capture an Array
of all arguments passed to the function that have not been matched to other arguments in the method signature. The splat operator can be used at the beginning or at the end of the argument list, though for the latter, the last argument that is passed into the function must be a Hash
.
1 2 3 4 5 6 7 8 9 10 11 |
|
1 2 3 4 5 6 7 8 9 10 |
|
There is one more —for the lack of a better word— interesting use of the splat operator in the method signature at the end when it’s by itself. It allows for additional arguments to be accepted, but ignored by the method.
1 2 3 4 5 6 |
|
Calling Methods
The reason for this blog entry is actually this section. I recently worked on a project in which I wanted to use Object#send
to dynamically call an instance method. The method #play
takes an argument, while #list
doesn’t. I quickly ran into a problem with this particular code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
When processing the input “list”, args
is set to nil
, which is still considered an argument and it triggers an ArgumentError
because #list
does not take any arguments.
Our little friend splat can actually help us resolve this issue. When calling a method and prepending the splat to an array variable, it will cause it to be distributed across the arguments of the method. In my case, the empty args
variable was distributed across exactly no arguments. By adding the splat, we can now dynamically send either one or two arguments to the #send
function.
1 2 3 4 5 6 7 8 9 10 11 |
|
When using splat to distribute the values to the arguments, the count must match exactly. Also, only a splat in front of an empty Array
, Hash
or nil
will yield no value to argument assignment.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|