Class: Babl::Utils::Value

Inherits:
Struct
  • 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 & store permanently)

  • Constructor requires all arguments

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

  • The object is frozen

Goals :

  • Create completely immutable value objects

  • Fast comparison between instances (using precomputed hash values)

  • Low overhead (relies on native Ruby Struct)

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.new(*fields) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/babl/utils/value.rb', line 18

def self.new(*fields)
    fields = fields.map(&:to_sym)
    field_aliases = ::Array.new(fields.size) { |i| "v#{i}" }

    clazz = super(:_cached_hash, *fields)
    clazz.const_set(:FIELDS, fields)
    clazz.class_eval "        def initialize(\#{field_aliases.join(',')})\n            super(\#{['nil', field_aliases].join(',')})\n            hash\n            freeze\n        end\n    RUBY\n\n    clazz\nend\n"

.with(hash = Utils::Hash::EMPTY) ⇒ Object

Raises:

  • (::ArgumentError)


43
44
45
46
# File 'lib/babl/utils/value.rb', line 43

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

Instance Method Details

#==(other) ⇒ Object



39
40
41
# File 'lib/babl/utils/value.rb', line 39

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

#hashObject



35
36
37
# File 'lib/babl/utils/value.rb', line 35

def hash
    self._cached_hash ||= super
end