Join arrays

535 views

What is the return value of the following Ruby code?

["a", *["b", "c"], "d"] * ?: # => ???

The correct answer is

["a:", "b:", "c:", "d:"]

"a:b:c:d"

["a:", ["b", "c"], "d:"]

It raises SyntaxError

Unlock Your Ruby Potential

Subscribe to RubyCademy and get free access to all our courses, plus hundreds of fun Ruby cards, quizzes, guides, and tutorials!

Explanation

Let's detail step-by-step what occurs in the following line of code

["a", *["b", "c"], "d"] * ?: # => "a:b:c:d"

Array Destructuring

*["b", "c"] concatenates the sub-array elements into the main array.

So after this operation, the array looks like this:

a = ["a", *["b", "c"], "d"]

a # => ["a", "b", "c", "d"]

This idiom is particularly used in CSV generation when the number of columns can only be known at runtime.

book = Book.preload(:authors).find(123)

row = [book.title, book.short_description, *book.authors.pluck(:fullname)]

row # => ["Hello", "A book about Hello", "Author 1", "Author 2", "Author 3"]

Single Character String

?: is a shorthand to create a single character string.

So

["a", "b", "c", "d"] * ?:

is equivalent to

["a", "b", "c", "d"] * ':'

Array#*

When Array#* takes a string as an argument, it acts like Array#join(sep).

Here

["a", "b", "c", "d"] * ':'

is equivalent to

["a", "b", "c", "d"].join(':')

So the return value of ["a", "b", "c", "d"] * ?: is "a:b:c:d".

Voilà!

Unlock Your Ruby Potential

Subscribe to RubyCademy and get free access to all our courses, plus hundreds of fun Ruby cards, quizzes, guides, and tutorials!

RubyCademy ©