Class: Hash

Inherits:
Object
  • Object
show all
Defined in:
lib/midwire_common/hash.rb

Overview

A more useful Hash class

Direct Known Subclasses

BottomlessHash

Instance Method Summary collapse

Instance Method Details

#apply_diff(changes, direction = :right) ⇒ Object

TODO: Spec/Test this method rubocop:disable Metrics/AbcSize



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/midwire_common/hash.rb', line 61

def apply_diff(changes, direction = :right)
  cloned = clone
  path = [[cloned, changes]]
  pos, local_changes = path.pop
  while local_changes
    local_changes.each_pair do |key, change|
      if change.is_a?(Array)
        pos[key] = (direction == :right) ? change[1] : change[0]
      else
        pos[key] = pos[key].clone
        path.push([pos[key], change])
      end
    end
    pos, local_changes = path.pop
  end
  cloned
end

#apply_diff!(changes, direction = :right) ⇒ Object

TODO: Spec/Test this method



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/midwire_common/hash.rb', line 43

def apply_diff!(changes, direction = :right)
  path = [[self, changes]]
  pos, local_changes = path.pop
  while local_changes
    local_changes.each_pair do |key, change|
      if change.is_a?(Array)
        pos[key] = (direction == :right) ? change[1] : change[0]
      else
        path.push([pos[key], change])
      end
    end
    pos, local_changes = path.pop
  end
  self
end

#bottomlessObject



15
16
17
# File 'lib/midwire_common/hash.rb', line 15

def bottomless
  BottomlessHash.from_hash(self)
end

#diff(other) ⇒ Object

rubocop:disable Metrics/AbcSize



28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/midwire_common/hash.rb', line 28

def diff(other)
  (keys + other.keys).uniq.each_with_object({}) do |key, memo|
    unless self[key] == other[key]
      memo[key] = if self[key].is_a?(Hash) && other[key].is_a?(Hash)
                    self[key].diff(other[key])
                  else
                    [self[key], other[key]]
                  end
    end
    memo
  end
end

#except(*keys) ⇒ Object

Usage { :a => 1, :b => 2, :c => 3}.except(:a) -> { :b => 2, :c => 3}



81
82
83
# File 'lib/midwire_common/hash.rb', line 81

def except(*keys)
  reject { |key, _v| keys.flatten.include?(key.to_sym) }
end

#grep(pattern) ⇒ Object

A better grep



20
21
22
23
24
25
# File 'lib/midwire_common/hash.rb', line 20

def grep(pattern)
  each_with_object([]) do |kv, res|
    res << kv if kv[0] =~ pattern || kv[1] =~ pattern
    res
  end
end

#only(*keys) ⇒ Object

Usage { :a => 1, :b => 2, :c => 3}.only(:a) -> => 1



86
87
88
# File 'lib/midwire_common/hash.rb', line 86

def only(*keys)
  dup.reject { |key, _v| !keys.flatten.include?(key.to_sym) }
end

#pop(*keys) ⇒ Object

Usage h = { :a => 1, :b => 2, :c => 3}.pop(:a) -> => 1 … and now h == { :b => 2, :c => 3}



92
93
94
95
96
# File 'lib/midwire_common/hash.rb', line 92

def pop(*keys)
  ret = reject { |key, _v| !keys.flatten.include?(key.to_sym) }
  reject! { |key, _v| keys.flatten.include?(key.to_sym) }
  ret
end

#recursively_symbolize_keys!Object

Recursively change keys to symbols Modifies the hash keys in place.



121
122
123
124
125
126
127
# File 'lib/midwire_common/hash.rb', line 121

def recursively_symbolize_keys!
  symbolize_keys!
  values.each do |value|
    value.recursively_symbolize_keys! if value.is_a?(Hash)
  end
  self
end

#symbolize_keysObject

rubocop:enable Style/RescueModifier



115
116
117
# File 'lib/midwire_common/hash.rb', line 115

def symbolize_keys
  dup.symbolize_keys!
end

#symbolize_keys!Object

rubocop:disable Style/RescueModifier



107
108
109
110
111
112
# File 'lib/midwire_common/hash.rb', line 107

def symbolize_keys!
  keys.each do |key|
    self[(key.to_sym rescue key) || key] = delete(key)
  end
  self
end

#to_query_stringObject

Usage { :a => 1, :b => 2, :c => 3}.to_query_string #= a=1&b=2&c=3



99
100
101
102
103
104
# File 'lib/midwire_common/hash.rb', line 99

def to_query_string
  require 'uri'
  map do |key, value|
    "#{URI.encode(key.to_s)}=#{URI.encode(value.to_s)}"
  end.join('&')
end