The Ruby splat operator is confusing and here is why: it does two things that are the exact opposite of each other. Let me explain…
It destructures an array, which looks something like this:
x, y, z = *[1,2,3] puts x # => 1 puts y # => 2 puts z # => 3
But it can also be used to construct an array:
x = *123 # => 
If you think about this, it is doing two very different things.
One takes an array and removes the surrounding square brackets
* becomes 123
The other takes a value and adds the surrounding square brackets
*123 becomes 
The only question we need to answer then is when does it destruct and when does it construct? 🤔
If you use it when defining a method it will take any argument you give it and construct it into an array.
def describe_args(*args) puts args puts args.class end describe_args(1,2,3) # 1 # 2 # 3 # Array
If you use it when passing arguments as an array to a method it will deconstruct the array into arguments.
def describe_first_arg(x,y,z) puts x puts x.class end describe_first_arg(*[1,2,3]) # 1 # Integer
Hopefully, we can now understand a class method you may have come across:
def self.perform(*args) new(*args).perform end
At first glance this looks strange and complex but using our newfound understanding of the splat operator we can understand what this is doing.
class SumTotal def self.perform(*args) # this splat operator will construct any arguments into an array new(*args).perform # this splat operator will deconstruct that array into arguments end def initialize(x,y) @x = x @y = y end def perform puts @x + @y end end SumTotal.perform(5,5) # => 10
SumTotal.perform(5,5) # => 10
sum_total = SumTotal.new(5,5) sum_total.perform # => 10
class SumTotal def self.perform(*args) new(*args).perform end def initialize(x,y,z) @x = x @y = y @z = z end def perform puts @x + @y + @z end end SumTotal.perform(5,5,5) # => 15
perform method have changed but we can make those changes without having to worry about the
self.perform class method.
Thank you to Starr Horne’s article Using splats to build up and tear apart arrays in Ruby, which helped to shape my understanding.