Class: Plines::IndifferentHash

Inherits:
Hash
  • Object
show all
Defined in:
lib/plines/indifferent_hash.rb

Overview

Provides a hash that can be accessed by symbol or string keys. This is useful because a plines job batch data hash is commonly provided with symbol keys, but after round-tripping through JSON it is converted to strings. We can’t safely convert all strings to symbols (as symbols are never GC’d) so instead we use this for the data hash.

Constant Summary collapse

NotAHashError =
Class.new(TypeError)
ConflictingEntriesError =
Class.new(ArgumentError)

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.from(original) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/plines/indifferent_hash.rb', line 16

def self.from(original)
  unless original.is_a?(Hash) || original.is_a?(IndifferentHash)
    raise NotAHashError, "Expected a hash, got #{original.inspect}"
  end

  indif = Hash.new { |hash, key| hash[key.to_s] if Symbol === key }

  original.each do |key, value|
    key = key.to_s

    if indif.has_key?(key)
      raise ConflictingEntriesError,
        "Hash has conflicting entries for #{key}: #{original}"
    end

    indif[key] = indifferent(value)
  end

  new(indif)
end

.indifferent(object) ⇒ Object



37
38
39
40
41
42
43
# File 'lib/plines/indifferent_hash.rb', line 37

def self.indifferent(object)
  case object
  when Hash  then from(object)
  when Array then object.map { |o| indifferent(o) }
  else object
  end
end

Instance Method Details

#fetch(key) ⇒ Object



45
46
47
48
49
50
51
# File 'lib/plines/indifferent_hash.rb', line 45

def fetch(key)
  if !has_key?(key) && Symbol === key && has_key?(key.to_s)
    key = key.to_s
  end

  super
end

#merge(other) ⇒ Object



53
54
55
# File 'lib/plines/indifferent_hash.rb', line 53

def merge(other)
  IndifferentHash.from super(IndifferentHash.from other)
end