fuzzyhash 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
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