Skip to content

End of Life Ruby 3.2 has reached end of life and gets no more fixes. Switch to Ruby 4.0 →

class method

Data.new

new(*args) → instance
new(**kwargs) → instance
::[](*args) → instance
::[](**kwargs) → instance

Constructors for classes defined with ::define accept both positional and keyword arguments.

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

Measure.new(1, 'km')
#=> #<data Measure amount=1, unit="km">
Measure.new(amount: 1, unit: 'km')
#=> #<data Measure amount=1, unit="km">

# Alternative shorter intialization with []
Measure[1, 'km']
#=> #<data Measure amount=1, unit="km">
Measure[amount: 1, unit: 'km']
#=> #<data Measure amount=1, unit="km">

All arguments are mandatory (unlike Struct), and converted to keyword arguments:

Example
Measure.new(amount: 1)
# in `initialize': missing keyword: :unit (ArgumentError)

Measure.new(1)
# in `initialize': missing keyword: :unit (ArgumentError)

Note that Measure#initialize always receives keyword arguments, and that mandatory arguments are checked in initialize, not in new. This can be important for redefining initialize in order to convert arguments or provide defaults:

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

  def initialize(amount:, unit: NONE.new)
    super(amount: Float(amount), unit:)
  end
end

Measure.new('10', 'km') # => #<data Measure amount=10.0, unit="km">
Measure.new(10_000)     # => #<data Measure amount=10000.0, unit=#<data NONE>>
See also .members #== .define #deconstruct also in 4.1 · 4.0 · 3.4 · 3.3