class Data

Die Klasse Data bietet eine bequeme Möglichkeit, einfache Klassen für wertähnliche Objekte zu definieren.

Das einfachste Anwendungsbeispiel

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"

Das konstruierte Objekt hat auch vernünftige Definitionen für den == Operator, die to_h Hash-Konvertierung und deconstruct / deconstruct_keys für die Verwendung in der Mustererkennung.

Die Methode ::define akzeptiert einen optionalen Block und wertet ihn im Kontext der neu definierten Klasse aus. Dies ermöglicht die Definition zusätzlicher Methoden.

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 bietet keine Member-Writer oder Enumeratoren: Es ist als Speicher für unveränderliche atomare Werte gedacht. Beachten Sie jedoch, dass, wenn einige der Datenmember einer veränderlichen Klasse angehören, Data keine zusätzliche Unveränderlichkeitsprüfung durchführt.

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"]>

Siehe auch Struct, was ein ähnliches Konzept ist, aber eine eher Container-ähnliche API hat, die es ermöglicht, den Inhalt des Objekts zu ändern und es zu durchlaufen.