fuzzyhash 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :minor: 0
3
- :patch: 7
3
+ :patch: 8
4
4
  :major: 0
data/lib/fuzzy_hash.rb CHANGED
@@ -1,112 +1,135 @@
1
+ require 'set'
2
+
1
3
  class FuzzyHash
4
+
5
+ def self.always_fuzzy(init_hash = nil)
6
+ hash = new(init_hash)
7
+ hash.classes_to_fuzz = nil
8
+ hash
9
+ end
10
+
11
+ attr_accessor :classes_to_fuzz
2
12
 
3
- def initialize(init_hash = nil)
4
- @regexes = []
13
+ def initialize(init_hash = nil, classes_to_fuzz = nil)
14
+ @fuzzies = []
5
15
  @hash_reverse = {}
6
- @regexes_reverse = {}
16
+ @fuzzies_reverse = {}
7
17
  @hash = {}
18
+ @classes_to_fuzz = classes_to_fuzz || [Regexp]
19
+ @classes_to_fuzz = Set.new(@classes_to_fuzz)
8
20
  init_hash.each{ |key,value| self[key] = value } if init_hash
9
21
  end
10
22
 
11
23
  def clear
12
- @hash.clear
13
- @regexes.clear
14
- @hash_reverse.clear
15
- @regexes_reverse.clear
24
+ hash.clear
25
+ fuzzies.clear
26
+ hash_reverse.clear
27
+ fuzzies_reverse.clear
16
28
  end
17
29
 
18
30
  def size
19
- @hash.size + @regexes.size
31
+ hash.size + fuzzies.size
20
32
  end
21
33
  alias_method :count, :size
22
34
 
23
35
 
24
36
  def ==(o)
25
37
  o.is_a?(FuzzyHash)
26
- o.instance_variable_get(:@hash) == @hash &&
27
- o.instance_variable_get(:@regexes) == @regexes
38
+ o.send(:hash) == hash &&
39
+ o.send(:fuzzies) == fuzzies
28
40
  end
29
41
 
30
42
  def empty?
31
- @hash.empty? && @regexes.empty?
43
+ hash.empty? && fuzzies.empty?
32
44
  end
33
45
 
34
46
  def keys
35
- @hash.keys + @regexes.collect{|r| r.first}
47
+ hash.keys + fuzzies.collect{|r| r.first}
36
48
  end
37
49
 
38
50
  def values
39
- @hash.values + @regexes.collect{|r| r.last}
51
+ hash.values + fuzzies.collect{|r| r.last}
40
52
  end
41
53
 
42
54
  def each
43
- @hash.each{|k,v| yield k,v }
44
- @regexes.each{|v| yield v.first, v.last }
55
+ hash.each{|k,v| yield k,v }
56
+ fuzzies.each{|v| yield v.first, v.last }
45
57
  end
46
58
 
47
59
  def delete_value(value)
48
- @hash.delete(@hash_reverse[value]) || ((rr = @regexes_reverse[value]) && @regexes.delete_at(rr[0]))
60
+ hash.delete(hash_reverse[value]) || ((rr = fuzzies_reverse[value]) && fuzzies.delete_at(rr[0]))
49
61
  end
50
62
 
51
63
  def []=(key, value)
52
- case key
53
- when Regexp
54
- @regexes << [key, value]
55
- @regex_test = nil
56
- @regexes_reverse[value] = [@regexes.size - 1, key, value]
64
+ if classes_to_fuzz.nil? || classes_to_fuzz.include?(key.class)
65
+ fuzzies.delete_if{|f| f.first.hash == key.hash}
66
+ fuzzies_reverse.delete_if{|k, v| v.hash == key.hash}
67
+
68
+ fuzzies << [key, value]
69
+ reset_fuzz_test!
70
+ fuzzies_reverse[value] = [fuzzies.size - 1, key, value]
57
71
  else
58
- @hash[key] = value
59
- @hash_reverse[value] = key
72
+ hash[key] = value
73
+ hash_reverse.delete_if{|k,v| v.hash == key.hash}
74
+ hash_reverse[value] = key
60
75
  end
61
76
  value
62
77
  end
63
78
 
64
79
  def replace(src, dest)
65
- if @hash_reverse.key?(src)
66
- key = @hash_reverse[src]
67
- @hash[key] = dest
68
- @hash_reverse.delete(src)
69
- @hash_reverse[dest] = key
70
- elsif @regexes_reverse.key?(src)
71
- key = @regexes_reverse[src]
72
- @regexes[rkey[0]] = [rkey[1], dest]
73
- @regexes_reverse.delete(src)
74
- @regexes_reverse[dest] = [rkey[0], rkey[1], dest]
80
+ if hash_reverse.key?(src)
81
+ key = hash_reverse[src]
82
+ hash[key] = dest
83
+ hash_reverse.delete(src)
84
+ hash_reverse[dest] = key
85
+ elsif fuzzies_reverse.key?(src)
86
+ key = fuzzies_reverse[src]
87
+ fuzzies[rkey[0]] = [rkey[1], dest]
88
+ fuzzies_reverse.delete(src)
89
+ fuzzies_reverse[dest] = [rkey[0], rkey[1], dest]
75
90
  end
76
91
  end
77
92
 
78
93
  def [](key)
79
- @hash.key?(key) ? @hash[key] : (lookup = regex_lookup(key)) && lookup && lookup.first
94
+ hash.key?(key) ? hash[key] : (lookup = fuzzy_lookup(key)) && lookup && lookup.first
80
95
  end
81
96
 
82
97
  def match_with_result(key)
83
- if @hash.key?(key)
84
- [@hash[key], key]
98
+ if hash.key?(key)
99
+ [hash[key], key]
85
100
  else
86
- regex_lookup(key)
101
+ fuzzy_lookup(key)
87
102
  end
88
103
  end
89
104
 
90
105
  private
91
- def regex_test
92
- unless @regex_test
93
- @regex_test = Object.new
94
- @regex_test.instance_variable_set(:'@regexes', @regexes)
106
+ attr_reader :fuzzies, :hash_reverse, :fuzzies_reverse, :hash
107
+ attr_writer :fuzz_test
108
+
109
+ def reset_fuzz_test!
110
+ self.fuzz_test = nil
111
+ end
112
+
113
+ def fuzz_test
114
+ unless @fuzz_test
115
+ @fuzz_test = Object.new
116
+ @fuzz_test.instance_variable_set(:'@fuzzies', fuzzies)
95
117
  method = "
96
118
  def match(str)
97
119
  case str
98
120
  "
99
- @regexes.each_with_index do |reg, index|
100
- method << "when #{reg.first.inspect}: [@regexes[#{index}][1], str]\n"
121
+ fuzzies.each_with_index do |reg, index|
122
+ method << "when #{reg.first.inspect}: [@fuzzies[#{index}][1], str]\n"
101
123
  end
102
124
  method << "end\nend\n"
103
- @regex_test.instance_eval method
125
+
126
+ @fuzz_test.instance_eval method
104
127
  end
105
- @regex_test
128
+ @fuzz_test
106
129
  end
107
130
 
108
- def regex_lookup(key)
109
- if !@regexes.empty? && key.is_a?(String) && (value = regex_test.match(key))
131
+ def fuzzy_lookup(key)
132
+ if !fuzzies.empty? && (value = fuzz_test.match(key))
110
133
  value
111
134
  end
112
135
  end
@@ -8,12 +8,26 @@ describe "Fuzzy hash" do
8
8
  l['asd'].should == 'qwe'
9
9
  end
10
10
 
11
+ it "should accept strings, but the second time you set the same string, it should overwrite" do
12
+ l = FuzzyHash.new
13
+ l['asd'] = 'asd'
14
+ l['asd'] = 'qwe'
15
+ l['asd'].should == 'qwe'
16
+ end
17
+
11
18
  it "should accept regexs too" do
12
19
  l = FuzzyHash.new
13
20
  l[/asd.*/] = 'qwe'
14
21
  l['asdqweasd'].should == 'qwe'
15
22
  end
16
23
 
24
+ it "should accept regexs too, but the second time you set the same regex, it should overwrite" do
25
+ l = FuzzyHash.new
26
+ l[/asd/] = 'asd'
27
+ l[/asd/] = 'qwe'
28
+ l['asdqweasd'].should == 'qwe'
29
+ end
30
+
17
31
  it "should accept regexs too with the match" do
18
32
  l = FuzzyHash.new
19
33
  l[/asd.*/] = 'qwe'
@@ -45,6 +59,19 @@ describe "Fuzzy hash" do
45
59
  l['false'].should == 'everything else'
46
60
  end
47
61
 
62
+ it "always fuzzy should accept .. well.. anything" do
63
+ l = FuzzyHash.always_fuzzy
64
+ l[1..3] = '1 to 3'
65
+ l[4] = 'four'
66
+ l[5..10] = '5 and up'
67
+ l[/.*/] = 'whatev'
68
+
69
+ l[2].should == '1 to 3'
70
+ l[4].should == 'four'
71
+ l[8].should == '5 and up'
72
+ l['something'].should == 'whatev'
73
+ end
74
+
48
75
  it "should pick between the correct regex" do
49
76
  hash = FuzzyHash.new
50
77
  hash[/^\d+$/] = 'number'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fuzzyhash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joshua Hull
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-09-25 00:00:00 -04:00
12
+ date: 2009-10-11 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies: []
15
15