A very small library to help you define and create immutable value objects. Mainly to reduce the amount of code I needed for ActiveRecord composed_of classes.


Start off by creating a class which derives from ValueObject::Base. Call has_fields to define a list of fields for the class.

class Route < ValueObject::Base
  has_fields :from, :to

You can now create instances of this class with positional arguments:

m1_motorway    ="London", "Leeds")
channel_tunnel ="Calais", "Dover")

Or with hashes:

route_66 = => "Santa Monica", :to => "Chicago")

You can read their attributes, but you can't write them.

m1_motorway.from     # => "London"    # => "Dover"
route_66.from = "IL" # => NoMethodError

You can test whether they are equal with == or eql?, which are aliases.

m1_motorway == channel_tunnel                 # => false
m1_motorway.eql?("London", "Leeds)) # => true

You can also create instances where all values are nil. Objects like this will return true when sent the message empty? (and will)

m1_motorway.empty?         # => false, nil).empty? # => true

You can even subclass them again to add more fields!

class Railway < Route
  has_fields :serviced_by

a_railway ="Aberdeen", "Inverness", "ScotRail")

a_railway.height     # => '6 foot 3'
a_railway.weight     # => '235 lbs'
a_railway.power      # => 'flies'

Create a hash from a value object by sending to_hash.

# => {
       :from        => "Aberdeen",
       :to          => "Inverness",
       :serviced_by => "ScotRail"

copy_with allows you to make a copy of a value object while updating certain attributes.

a_railway.copy_with(:serviced_by => "Virgin")
# => #<Railway:0x3914490

Value objects also define hash, which depends on the values of the fields as well as the class of which they are an instance.

a_railway.hash            # => 1160641176