The splat operator is confusing and here is why…
It does 2 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
#=> [123]
If you think about this, it is doing two very different things.
One takes an array and removes the surrounding [].
[123]
becomes 123
The other takes a value and adds the surrounding [].
*123
becomes [123]
.
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 do_a_thing(*args)
puts args
puts args.class
end
do_a_thing(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 do_a_thing(x,y,z)
puts x
puts x.class
end
do_a_thing(*[1,2,3])
# 1
# Integer
Hopefully now we can understand code that looks like this:
class Thing
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,z)
@x = x
@y = y
@z = z
end
def perform
puts @x
end
end
Thing.perform(1,2,3)
# => 1
As an aside, the reason for the above class method of perform
, is so you can easily call
Thing.perform()
, without having to first instantiate the object.
Using *args
means that if our expected parameters in the initialize
method were to change
we would never have to change them in the perform
class method.
Credit to this article which helped to shape my understanding.