# Ruby splat operator π

Sami Birnbaum
Edited by thoughtbot

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]
``````

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.