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