Skip to content
Simple immutable value objects for ruby (the readme is longer than the code)
Branch: master
Clone or download
Latest commit 121e18d Mar 22, 2017
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
lib Add comment to performance optimization Mar 22, 2017
spec Restrict SimpleCov to Ruby >= 2.2 Aug 20, 2016
.document Initial commit to values. Mar 19, 2011
.gitignore Git ignore local RVM conf (.ruby-version, -gemset) Jun 9, 2015
.rspec
.travis.yml Allow sudo on Travis to fix Rubinius Feb 17, 2017
.yardopts Add yard gems and basic yard options Jun 29, 2015
Gemfile Fix test breakage due to newer Rake incompatibility Feb 17, 2017
HISTORY.md Update HISTORY.md Aug 20, 2016
LICENSE.txt Add Marc to gem authors and license Jun 29, 2015
README.md s/less/fewer Jun 30, 2015
Rakefile modernise rake file Mar 1, 2015
values.gemspec bump version Jul 1, 2015

README.md

Values

Gem Version Gem Downloads CI Build Status Code Coverage Yard Docs

Summary

Values is a tiny library for creating value objects in ruby.

Classes created using Value mostly look like classes created using Struct or OpenStruct, but fix two problems with those:

Problems with Struct and OpenStruct

Struct and OpenStruct constructors can take fewer than the default number of arguments and set other fields as nil:

Point = Struct.new(:x, :y)
Point.new(1)
# => #<struct Point x=1, y=nil>
p = OpenStruct.new(x: 1)
# => #<OpenStruct x=1>
p.y
# => nil

Struct and OpenStruct objects are mutable:

p = Point.new(1, 2)
p.x = 2
p.x
# => 2
p = OpenStruct.new(x: 1, y: 2)
p.x = 2
p.x
# => 2

Values is Better

Values fixes both of the above problems.

Constructors require expected arguments:

Point = Value.new(:x, :y)
Point.new(1)
# => ArgumentError: wrong number of arguments, 1 for 2
# from /Users/tcrayford/Projects/ruby/values/lib/values.rb:7:in `block (2 levels) in new
# from (irb):5:in new
# from (irb):5
# from /usr/local/bin/irb:12:in `<main>

Instances are immutable:

p = Point.new(1, 2)
p.x = 1
# => NoMethodError: undefined method x= for #<Point:0x00000100943788 @x=0, @y=1>
# from (irb):6
# from /usr/local/bin/irb:12:in <main>

Features

Values also provides an alternative constructor which takes a hash:

p = Point.with(x: 3, y: 4)
p.x
# => 3

Values can copy and replace fields using a hash:

p = Point.with(x: 1, y: -1)
q = p.with(y: 2)
# => #<Point x=1, y=2>

Value classes can be converted to a hash, like OpenStruct:

Point.with(x: 1, y: -1).to_h
# => {:x=>1, :y=>-1}

Values also supports customization of value classes inheriting from Value.new:

class Point < Value.new(:x, :y)
  def to_s
    "<Point at (#{x}, #{y})>"
  end
end

p = Point.new(1, 2)
p.to_s
# => "<Point at (1, 2)>"

Values does NOT have all the features of Struct or OpenStruct (nor is it meant to).

You can’t perform that action at this time.