Skip to content
On this page
class · Ruby 4.0 · added in Ruby 3.2

Data

< Object 10 instance methods 3 class methods

Class Data provides a convenient way to define simple classes for value-alike objects.

The simplest example of usage:

Example
Measure = Data.define(:amount, :unit)

# Positional arguments constructor is provided
distance = Measure.new(100, 'km')
#=> #<data Measure amount=100, unit="km">

# Keyword arguments constructor is provided
weight = Measure.new(amount: 50, unit: 'kg')
#=> #<data Measure amount=50, unit="kg">

# Alternative form to construct an object:
speed = Measure[10, 'mPh']
#=> #<data Measure amount=10, unit="mPh">

# Works with keyword arguments, too:
area = Measure[amount: 1.5, unit: 'm^2']
#=> #<data Measure amount=1.5, unit="m^2">

# Argument accessors are provided:
distance.amount #=> 100
distance.unit #=> "km"

Constructed object also has a reasonable definitions of == operator, to_h hash conversion, and deconstruct / deconstruct_keys to be used in pattern matching.

::define method accepts an optional block and evaluates it in the context of the newly defined class. That allows to define additional methods:

Example
Measure = Data.define(:amount, :unit) do
  def <=>(other)
    return unless other.is_a?(self.class) && other.unit == unit
    amount <=> other.amount
  end

  include Comparable
end

Measure[3, 'm'] < Measure[5, 'm'] #=> true
Measure[3, 'm'] < Measure[5, 'kg']
# comparison of Measure with Measure failed (ArgumentError)

Data provides no member writers, or enumerators: it is meant to be a storage for immutable atomic values. But note that if some of data members is of a mutable class, Data does no additional immutability enforcement:

Example
Event = Data.define(:time, :weekdays)
event = Event.new('18:00', %w[Tue Wed Fri])
#=> #<data Event time="18:00", weekdays=["Tue", "Wed", "Fri"]>

# There is no #time= or #weekdays= accessors, but changes are
# still possible:
event.weekdays << 'Sat'
event
#=> #<data Event time="18:00", weekdays=["Tue", "Wed", "Fri", "Sat"]>

See also Struct, which is a similar concept, but has more container-alike API, allowing to change contents of the object and enumerate it.

Class methods 3

Instance methods 10

Ruby version changes 1

  1. 3.2
    • New core class to represent simple immutable value object. The class is similar to Struct and partially shares an implementation, but has more lean and strict API. [Feature #16122]

      Example
      Measure = Data.define(:amount, :unit)
      distance = Measure.new(100, 'km')            #=> #<data Measure amount=100, unit="km">
      weight = Measure.new(amount: 50, unit: 'kg') #=> #<data Measure amount=50, unit="kg">
      weight.with(amount: 40)                      #=> #<data Measure amount=40, unit="kg">
      weight.amount                                #=> 50
      weight.amount = 40                           #=> NoMethodError: undefined method `amount='