#!/usr/bin/env ruby require 'irb' require 'irb/completion' require 'awesome_print' require 'bundler/setup' Bundler.require class Truck < ContractValueObject class Wheel < ContractValueObject attributes( size: Optional[Enum[:xs, :s, :m, :l, :xl]], ) defaults( size: :m, ) end attributes( color: Enum[:red, :white, :blue], model: String, wheels: ArrayOf[Wheel], ) private def wheels=(wheels) # transform all the inputs into wheels if wheels.all? { |wheel| wheel.is_a?(Symbol) } wheels = wheels.map do |size| Wheel.new(size: size) end end # make sure that wheels behave rationally raise ArgumentError, 'All of the wheels should be the same size' if wheels.uniq(&:size).count != 1 @wheels = wheels end end TRUCK = Truck.new( wheels: [Truck::Wheel.new, Truck::Wheel.new, Truck::Wheel.new, Truck::Wheel.new], color: :red, model: 'Ford F150', ) IRB.start