Values
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:
“by Point = Struct.new(:x, :y) Point.new(1)
=> #Maruku could not parse this XML/HTML:
<struct Point x=1, y=nil>
Maruku could not parse this XML/HTML:
<struct Point x=1, y=nil>
“
“by p = OpenStruct.new(x: 1)
=> #Maruku could not parse this XML/HTML:
<OpenStruct x=1>
Maruku could not parse this XML/HTML:
<OpenStruct x=1>
p.y
=> nil
“
Struct and OpenStruct objects are mutable:
“by p = Point.new(1, 2) p.x = 2 p.x
=> 2
“
“by 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:
“by 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:
“by 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 Maruku could not parse this XML/HTML:
<main>
Maruku could not parse this XML/HTML:
<main>
“
Features
Values also provides an alternative constructor which takes a hash:
“by p = Point.with(x: 3, y: 4) p.x
=> 3
“
Values can copy and replace fields using a hash:
“by p = Point.with(x: 1, y: -1) q = p.with(y: 2)
=> #Maruku could not parse this XML/HTML:
<Point x=1, y=2>
Maruku could not parse this XML/HTML:
<Point x=1, y=2>
“
Value classes can be converted to a hash, like OpenStruct:
“by Point.with(x: 1, y: -1).to_h
=>
“
Values also supports customization of value classes inheriting from Value.new
:
“by class Point < Value.new(:x, :y) def to_s “
Maruku could not parse this XML/HTML:
<Point at (#{x}, #{y})>"
end
end
p = Point.new(1, 2) p.to_s
=> “Maruku could not parse this XML/HTML:
<Point at (1, 2)>"
Maruku could not parse this XML/HTML:
<Point at (1, 2)>"
“
Values does NOT have all the features of Struct or OpenStruct (nor is it meant to).