Today I learned
Read about some cool stuff.
Ruby class deconstruction
21 sie 2025

Ruby class deconstruction is quite intuitive and essentially reuses array and hash deconstruction via the deconstruct and deconstruct_keys methods.

class Result
  attr_reader :success, :info

  def initialize(success:, info:)
    @success = success
    @info = info
  end

  def deconstruct
    [ @success, @info ]
  end

  def deconstruct_keys(*)
    { success:, info: }
  end
end

You can think of this as automatic type conversion before deconstruction.


There are two common ways of deconstructing in Ruby. One is using the rightward assignment operator =>.

result = Result.new(success: false, info: 'Not enough potatoes' )

result => x, y

puts x # false
puts y # Not enough potatoes

result => { info:, success: }

puts info # Not enough potatoes
puts success # false

The other is using pattern matching:

case result
in true, info
  puts "Success with info: #{info}"
in false, info
  puts "Failure with info: #{info}" # Failure with info: Not enough potatoes
end

case result
in success: true, info:
  puts "Success with info: #{info}"
in success: false, info:
  puts "Failure with info: #{info}" # Failure with info: Not enough potatoes
end

You can also match specific classes:

SomethingElse = Struct.new(:success, :info)
record = SomethingElse.new(true, 'All good')

case record
in Result[info:]
in SomethingElse(info:) # [] and () are interchangeable
  puts "info: #{info}" # info: All good
end

Ruby's built-in Struct supports deconstruction out of the box.


Since [] is just a regular Ruby method, you can design a clean and expressive interface with it:

class Container
  def self.[](value)
    new(value)
  end

  def initialize(value)
    @value = value
  end

  def deconstruct
    [ @value ]
  end
end

case Container[42]
in Container[value]
  puts "Value is: #{value}" # Value is: 42
end

This way, the initialization Container[42] and the deconstruction Container[value] share the same interface.

ul. Powstańców Warszawy 5
15-129 Białystok
+48 668 842 999
SKONTAKTUJ SIĘ Z NAMI