# Ruby Tuesday – Array Decomposition

Today’s Ruby Tuesday takes a look at Array Decomposition.

Ruby gives you some ability to destructure, or decompose, an `Array` into its component pieces.

Say we have an `Array` which represents a point in two-dimensional Cartesian space, we can decompose that array into its `x` and `y` coordinates, by doing an assignment of `x` and `y` to the point represented by the given `Array`, if we wrap them in parenthesis.

```(x, y) = [1, -1]
# => [1, -1]
x
# => 1
y
# => -1
```

If we want to decompose only part of the `Array`, and save off anything at the end, we can use a `*` before the last variable in the assignment.

```(_, second, *rest) = [:a, :b, :c, :d]
# => [:a, :b, :c, :d]
```

The capturing even works, if there are less items in the array than there are variables to decompose into.

```(_, second, *rest) = [:a]
# => [:a]
second
# => nil
rest
# => []
```

We can also use Array Decomposition in method arguments to decompose a passed in `Array` to individual variable for specific elements.

```def cartesian_point((x, y))
puts "x: #{x}, y: #{y}"
end
# => :cartesian_point

cartesian_point([1, -1])
# x: 1, y: -1
# => nil
```

Above I mentioned that we can capture the “rest” of the `Array` we aren’t wanting to decompose at this point by using a `*` (called the “splat” operator).

```(head, *rest) = [1, 2, 3, 4, 5]
# => [1, 2, 3, 4, 5]
# => 1
rest
# => [2, 3, 4, 5]
```

So let’s see what we get when we use the splat to capture the rest of an `Array` that is smaller than what is at the end.

```(first, *tail) = 
# => 
first
# => 1
tail
# => []
```

We get an empty list.

Let’s see what we get on the decomposition for an empty list, into the items, and a capturing “rest” variable.

```(h, *t) = []
# => []
h
# => nil
t
# => []
```

We get a `nil` as part of the binding, and we still get an empty array the “rest” of the items.

This means we can use destructing to handle recursing a list, and have a guard clause that checks if we received and empty `Array` by checking if the head of the `Array` is `nil`, and then just recurse by passing in the tail as the argument when recursing.

```def recurse_list((head, *tail))
recurse_list(tail)
else
puts "all done"
end
end
# => :recurse_list

recurse_list([1, 2, 3, 4, 5, 6, 7])
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# all done
# => nil
```

–Proctor