Class: Hashery::FuzzyHash
Overview
FuzzyHash is a weird hash with special semantics for regex keys.
This is useful when you want to have a lookup table that can either contain strings or regexes. For instance, you might want a catch all for certain regexes that perform a certain logic.
>> hash = FuzzyHash.new
>> hash[/^\d+$/] = 'number'
>> hash[/.*/] = 'something'
>> hash['chunky'] = 'bacon'
>> hash['foo'] = 'vader'
>> hash['foo']
<< 'vader'
>> hash['food']
<< 'something'
>> hash['123']
<< 'number'
This class is based on Joshua Hull’s original FuzzyHash class.
Instance Attribute Summary collapse
- #fuzz_test ⇒ Object private
-
#fuzzies ⇒ Object
readonly
private
Returns the value of attribute fuzzies.
-
#fuzzies_reverse ⇒ Object
readonly
private
Returns the value of attribute fuzzies_reverse.
-
#fuzzy_hash ⇒ Object
readonly
private
Returns the value of attribute fuzzy_hash.
-
#hash ⇒ Object
readonly
private
Returns the value of attribute hash.
-
#hash_reverse ⇒ Object
readonly
private
Returns the value of attribute hash_reverse.
Instance Method Summary collapse
- #==(o) ⇒ Object
- #[](key) ⇒ Object
- #[]=(key, value) ⇒ Object
- #clear ⇒ Object
- #delete_value(value) ⇒ Object
- #each ⇒ Object
- #empty? ⇒ Boolean
- #fuzzy_lookup(key) ⇒ Object private
-
#initialize(init_hash = nil) ⇒ FuzzyHash
constructor
A new instance of FuzzyHash.
- #keys ⇒ Object
- #match_with_result(key) ⇒ Object
- #replace(src, dest) ⇒ Object
- #reset_fuzz_test! ⇒ Object private
- #size ⇒ Object (also: #count)
- #values ⇒ Object
Constructor Details
#initialize(init_hash = nil) ⇒ FuzzyHash
Returns a new instance of FuzzyHash.
30 31 32 33 34 35 36 37 |
# File 'lib/hashery/fuzzy_hash.rb', line 30 def initialize(init_hash = nil) @fuzzies = [] @hash_reverse = {} @fuzzies_reverse = {} @fuzzy_hash = {} @hash = {} init_hash.each{ |key,value| self[key] = value } if init_hash end |
Instance Attribute Details
#fuzz_test ⇒ Object (private)
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/hashery/fuzzy_hash.rb', line 176 def fuzz_test unless @fuzz_test @fuzz_test = Object.new @fuzz_test.instance_variable_set(:'@fuzzies', fuzzies) method = " def match(str) case str\n " fuzzies.each_with_index do |reg, index| method << "when #{reg.first.inspect}; [@fuzzies[#{index}][1], Regexp.last_match(0)];" end method << "end\nend\n" @fuzz_test.instance_eval method end @fuzz_test end |
#fuzzies ⇒ Object (readonly, private)
Returns the value of attribute fuzzies.
163 164 165 |
# File 'lib/hashery/fuzzy_hash.rb', line 163 def fuzzies @fuzzies end |
#fuzzies_reverse ⇒ Object (readonly, private)
Returns the value of attribute fuzzies_reverse.
163 164 165 |
# File 'lib/hashery/fuzzy_hash.rb', line 163 def fuzzies_reverse @fuzzies_reverse end |
#fuzzy_hash ⇒ Object (readonly, private)
Returns the value of attribute fuzzy_hash.
163 164 165 |
# File 'lib/hashery/fuzzy_hash.rb', line 163 def fuzzy_hash @fuzzy_hash end |
#hash ⇒ Object (readonly, private)
Returns the value of attribute hash.
163 164 165 |
# File 'lib/hashery/fuzzy_hash.rb', line 163 def hash @hash end |
#hash_reverse ⇒ Object (readonly, private)
Returns the value of attribute hash_reverse.
163 164 165 |
# File 'lib/hashery/fuzzy_hash.rb', line 163 def hash_reverse @hash_reverse end |
Instance Method Details
#==(o) ⇒ Object
61 62 63 64 65 |
# File 'lib/hashery/fuzzy_hash.rb', line 61 def ==(o) o.is_a?(FuzzyHash) o.send(:hash) == hash && o.send(:fuzzies) == fuzzies end |
#[](key) ⇒ Object
144 145 146 147 148 |
# File 'lib/hashery/fuzzy_hash.rb', line 144 def [](key) (hash.key?(key) && hash[key]) || ((lookup = fuzzy_lookup(key)) && lookup && lookup.first) || fuzzy_hash[key] end |
#[]=(key, value) ⇒ Object
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/hashery/fuzzy_hash.rb', line 106 def []=(key, value) if Regexp === key fuzzies.delete_if{|f| f.first.inspect.hash == key.inspect.hash} fuzzies_reverse.delete_if{|k, v| v[1].inspect.hash == key.inspect.hash} hash_reverse.delete_if{|k,v| v.inspect.hash == key.inspect.hash} fuzzy_hash[key] = value fuzzies << [key, value] reset_fuzz_test! fuzzies_reverse[value] = [fuzzies.size - 1, key, value] else hash[key] = value hash_reverse.delete_if{|k,v| v.hash == key.hash} hash_reverse[value] = key end value end |
#clear ⇒ Object
42 43 44 45 46 47 |
# File 'lib/hashery/fuzzy_hash.rb', line 42 def clear hash.clear fuzzies.clear hash_reverse.clear fuzzies_reverse.clear end |
#delete_value(value) ⇒ Object
99 100 101 |
# File 'lib/hashery/fuzzy_hash.rb', line 99 def delete_value(value) hash.delete(hash_reverse[value]) || ((rr = fuzzies_reverse[value]) && fuzzies.delete_at(rr[0])) end |
#each ⇒ Object
91 92 93 94 |
# File 'lib/hashery/fuzzy_hash.rb', line 91 def each hash.each{|k,v| yield k,v } fuzzies.each{|v| yield v.first, v.last } end |
#empty? ⇒ Boolean
70 71 72 |
# File 'lib/hashery/fuzzy_hash.rb', line 70 def empty? hash.empty? && fuzzies.empty? end |
#fuzzy_lookup(key) ⇒ Object (private)
196 197 198 199 200 |
# File 'lib/hashery/fuzzy_hash.rb', line 196 def fuzzy_lookup(key) if !fuzzies.empty? && (value = fuzz_test.match(key)) value end end |
#keys ⇒ Object
77 78 79 |
# File 'lib/hashery/fuzzy_hash.rb', line 77 def keys hash.keys + fuzzy_hash.keys end |
#match_with_result(key) ⇒ Object
153 154 155 156 157 158 159 |
# File 'lib/hashery/fuzzy_hash.rb', line 153 def match_with_result(key) if hash.key?(key) [hash[key], key] else fuzzy_lookup(key) end end |
#replace(src, dest) ⇒ Object
127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/hashery/fuzzy_hash.rb', line 127 def replace(src, dest) if hash_reverse.key?(src) key = hash_reverse[src] hash[key] = dest hash_reverse.delete(src) hash_reverse[dest] = key elsif fuzzies_reverse.key?(src) key = fuzzies_reverse[src] fuzzies[rkey[0]] = [rkey[1], dest] fuzzies_reverse.delete(src) fuzzies_reverse[dest] = [rkey[0], rkey[1], dest] end end |
#reset_fuzz_test! ⇒ Object (private)
169 170 171 |
# File 'lib/hashery/fuzzy_hash.rb', line 169 def reset_fuzz_test! self.fuzz_test = nil end |
#size ⇒ Object Also known as: count
52 53 54 |
# File 'lib/hashery/fuzzy_hash.rb', line 52 def size hash.size + fuzzies.size end |
#values ⇒ Object
84 85 86 |
# File 'lib/hashery/fuzzy_hash.rb', line 84 def values hash.values + fuzzies.collect{|r| r.last} end |