Project

ivo

0.0
No commit activity in last 3 years
No release in over 3 years
Library for creating immutable value objects (IVO)
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Development

~> 12
~> 3
 Project Readme

Ivo

Build Status

A library for creating immutable value objects.

Installation

gem install ivo

Benchmarks

See benchmarks.rb. Performed on ruby 2.7.1.

                                     user     system      total        real
StructClass.new                  0.197386   0.000671   0.198057 (  0.199379)
IvoClass.new                     0.217936   0.000635   0.218571 (  0.219348)
IvoClass.with                    0.246758   0.000268   0.247026 (  0.247232)
ConcurrentImmutableStruct.new    0.782822   0.000924   0.783746 (  0.784684)
ValueClass.new                   1.365290   0.001162   1.366452 (  1.368131)
ValueClass.with                  1.990921   0.001786   1.992707 (  1.994895)
ImmutableStructClass.new         1.939959   0.001735   1.941694 (  1.943927)
                                     user     system      total        real
OpenStruct.new                   0.542196   0.000978   0.543174 (  0.544024)
Ivo.call                         0.592088   0.001324   0.593412 (  0.595383)

Usage

Car = Ivo.new(:make, :model)

car = Car.new('Honda', 'Accord')

car.make    # "Honda"
car.model   # "Accord"
car.frozen? # true

Objects can also be instantiated with keywords:

car = Car.with(make: 'Honda', model: 'Accord')

Ivo.new also accepts a block for additional definitions:

Car = Ivo.new(:make, :model) do
  def to_s
    "#{make} #{model}"
  end
end

For one-off value objects (similar to OpenStruct):

car = Ivo.(make: 'Honda', model: 'Accord')

car.make    # "Honda"
car.model   # "Accord"
car.frozen? # true

Under the hood

This:

Car = Ivo.new(:make, :model) do
  def to_s
    "#{make} #{model}"
  end
end

is equivalent to:

class Car
  def self.with(make: nil, model: nil)
    new(make, model)
  end

  def initialize(make = nil, model = nil)
    @make = make
    @model = model
    freeze
  end

  attr_reader :make, :model

  def to_s
    "#{make} #{model}"
  end

  def ==(other)
    self.class == other.class && make == other.make && model == other.model
  end

  alias_method :eql?, :==

  def hash
    make.hash ^ model.hash
  end
end