Class: Babl::Utils::Value

Inherits:
Object
  • Object
show all
Defined in:
lib/babl/utils/value.rb

Overview

Construct deeply immutable value objects Similar to Struct, but:

  • Properties are assumed deeply immutable (#hash is assumed constant)

  • Constructor requires all arguments

  • #== has the same meaning as #eql?

Class Method Summary collapse

Class Method Details

.new(*fields) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/babl/utils/value.rb', line 9

def self.new(*fields)
    ::Class.new(::Struct.new(:_cached_hash, *fields)) do
        field_aliases = ::Array.new(fields.size) { |i| "v#{i}" }
        const_set(:FIELDS, fields.map(&:to_sym))
        class_eval <<-RUBY
            def initialize(#{field_aliases.join(',')})
                super(#{['nil', field_aliases].join(',')})
                hash
                freeze
            end

            def hash
                self._cached_hash ||= super
            end

            def ==(other)
                eql?(other)
            end

            def self.with(hash = {})
                raise ::ArgumentError unless ::Hash === hash && (hash.keys - FIELDS).empty?
                new(*FIELDS.map { |f| hash.fetch(f) })
            end
        RUBY
    end
end