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
# => 3But 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
# ArrayIf 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
# IntegerHopefully 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)
# => 1As 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.