On this page
End of Life Ruby 3.2 has reached end of life and gets no more fixes. Switch to Ruby 4.0 →
Data
Class Data provides a convenient way to define simple classes for value-alike objects.
The simplest example of usage:
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:
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:
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
-
3.2
-
New core class to represent simple immutable value object. The class is similar to
Structand partially shares an implementation, but has more lean and strict API. [Feature #16122]ExampleMeasure = 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='
-