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β¦
Destructuring
It destructures an array, which looks something like this:
x, y, z = *[1,2,3]
puts x
# => 1
puts y
# => 2
puts z
# => 3
Constructing
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 square brackets []
.
*[123] becomes 123
The other takes a value and adds the surrounding square brackets []
.
*123 becomes [123]
When does it destruct and when does it construct?
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
Practical application
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
The initialize
and 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.
Let’s work together!
Learn more about parterning with us and take the guesswork out of building great products.