Value Object

Posted Over 7 years ago. Visible to the public.

The main purpose of a value object is answer meaningful questions for our application.

class Temperature
  include Comparable

  def initialize(temperature)
    @temperature = Float(temperature) # in case of strings, hashes, arrays we should explicitly .freeze them
  end

  def cold?
    temperature < COLD_THRESHOLD # Celsius degrees
  end

  def <=>(other)
    temperature <=> other.temperature
  end

  def to_s
    temperature.to_s
  end
  
  # Hashing implementation (transformation of the object_id into an integer) 
  # which used in checking for unique entries.
  def hash
    temperature.hash # the value must remain constant during the life span of the process
  end
  alias eql? ==
  
  protected

  COLD_THRESHOLD = new(15)
  attr_reader :temperature
end

Temperature.new(3).cold?                  # => true
Temperature.new(3) > Temperature.new(20)  # => false
Temperature.new(3) == Temperature.new(3)  # => true
[Temperature.new(7), Temperature.new(20), Temperature.new(20)].uniq # => [7.0, 20.0]

We use a value @temperature to define its identity in hashing implementation? That's right! Because value objects define their identity by their value. 20°C is.. 20°C – and it will be always equal to 20°C.

Another implementation using a gem

There is a gem called Values Show archive.org snapshot which is a tiny library for creating simple immutable value objects for ruby. Here is an example from above but with values gem.

require 'values'

class Temperature < Value.new(:temperature)
  include Comparable

  def cold?
    self < COLD_THRESHOLD
  end

  def <=>(other)
    temperature <=> other.temperature
  end

  def to_s
    "#{temperature.to_s} °C"
  end

  protected

  COLD_THRESHOLD = new(15)
end

Temperature.new(3).cold?                 # => true
Temperature.new(3) > Temperature.new(20) # => false
Temperature.new(3) == Temperature.new(3) # => true
[Temperature.new(7), Temperature.new(20), Temperature.new(20)].uniq
# => [#<Temperature temperature=7>, #<Temperature temperature=20>]
Alexander M
Last edit
About 7 years ago
Alexander M
Posted by Alexander M to Ruby and RoR knowledge base (2016-11-23 10:49)