Hash destructuring

1347 views

What is the return value of the following Ruby code?

h = { a: 21, b: 42 }.freeze

[*h] # => ???

The correct answer is

It raises FrozenError

[[:a, 21], [:b, 42]]

[:a, 21, :b, 42]

[{ a: 21, b: 42 }]

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

Firstly, calling [*h] in this context doesn't modify the original hash h.

Instead, it transforms the hash into a new array without causing any FrozenError.

Let's break down the above Ruby code:

class MyHash < Hash
  def to_a
    puts "MyHash#to_a: #{super}"
  end
end

h = MyHash.new
h[:a] = 21
h[:b] = 42

[*h] # => MyHash#to_a -> [[:a, :b], [:c, 42]]

This Ruby code defines a custom class called MyHash that inherits from the built-in Hash class.

It adds a new method called MyHash#to_a, which overrides the same method in the parent class.

When you create an instance of MyHash and populate it with key-value pairs, you can use the splat operator [*h] to convert the hash into an array.

This triggers the custom MyHash#to_a method, which prints "MyHash#to_a: " and then invokes the original Hash#to_a method using super.

In this example, the output will be:

"MyHash#to_a: [[:a, 21], [:b, 42]]"

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 ©