joshbuddy-fuzzy_hash 0.0.1

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/Manifest.txt ADDED
@@ -0,0 +1,5 @@
1
+ Manifest.txt
2
+ Rakefile
3
+ fuzzy_hash.gemspec
4
+ lib/fuzzy_hash.rb
5
+ spec/lookup_spec.rb
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = Fuzzy Hash
2
+
3
+ This is useful when you want to have a lookup table that can either contain strings or regexes.
4
+ For instance, you might want a catch all for certain regexes that perform a certain logic.
5
+
6
+ >> hash = FuzzyHash.new
7
+ >> hash[/^\d+$/] = 'number'
8
+ >> hash[/.*/] = 'something'
9
+ >> hash['chunky'] = 'bacon'
10
+ >> hash['foo'] = 'vader'
11
+
12
+ >> hash['foo']
13
+ << 'vader'
14
+ >> hash['food']
15
+ << 'something'
16
+ >> hash['123']
17
+ << 'number'
data/Rakefile ADDED
@@ -0,0 +1,26 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |s|
4
+ s.name = "fuzzy_hash"
5
+ s.description = s.summary = "A weird hash with special semantics for regex keys"
6
+ s.email = "joshbuddy@gmail.com"
7
+ s.homepage = "http://github.com/joshbuddy/fuzzy_hash"
8
+ s.authors = ["Joshua Hull"]
9
+ s.files = FileList["[A-Z]*", "{lib,spec}/**/*"]
10
+ end
11
+ rescue LoadError
12
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
13
+ end
14
+
15
+ require 'spec'
16
+ require 'spec/rake/spectask'
17
+ task :spec => 'spec:all'
18
+ namespace(:spec) do
19
+ Spec::Rake::SpecTask.new(:all) do |t|
20
+ t.spec_opts ||= []
21
+ t.spec_opts << "-rubygems"
22
+ t.spec_opts << "--options" << "spec/spec.opts"
23
+ t.spec_files = FileList['spec/**/*_spec.rb']
24
+ end
25
+
26
+ end
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 0
4
+ :patch: 1
data/lib/fuzzy_hash.rb ADDED
@@ -0,0 +1,88 @@
1
+ class FuzzyHash
2
+
3
+ Version = '0.0.1'
4
+
5
+ def initialize
6
+ @hash = {}
7
+ @regexes = []
8
+ @hash_reverse = {}
9
+ @regexes_reverse = {}
10
+ end
11
+
12
+ def clear
13
+ @hash.clear
14
+ @regexes.clear
15
+ @hash_reverse.clear
16
+ @regexes_reverse.clear
17
+ end
18
+
19
+ def ==(o)
20
+ o.instance_variable_get(:@hash) == @hash &&
21
+ o.instance_variable_get(:@regexes) == @regexes
22
+ end
23
+
24
+ def empty?
25
+ @hash.empty? && @regexes.empty?
26
+ end
27
+
28
+ def keys
29
+ @hash.keys + @regexes.collect{|r| r.first}
30
+ end
31
+
32
+ def values
33
+ @hash.values + @regexes.collect{|r| r.last}
34
+ end
35
+
36
+ def each
37
+ @hash.each{|k,v| yield k,v }
38
+ @regexes.each{|v| yield v.first, v.last }
39
+ end
40
+
41
+ def delete_value(value)
42
+ @hash.delete(@hash_reverse[value]) || ((rr = @regexes_reverse[value]) && @regexes.delete_at(rr[0]))
43
+ end
44
+
45
+ def []=(key, value)
46
+ case key
47
+ when Regexp
48
+ @regexes << [key, value]
49
+ @regex_test = nil
50
+ @regexes_reverse[value] = [@regexes.size - 1, key, value]
51
+ else
52
+ @hash[key] = value
53
+ @hash_reverse[value] = key
54
+ end
55
+ end
56
+
57
+ def replace(src, dest)
58
+ if @hash_reverse.key?(src)
59
+ key = @hash_reverse[src]
60
+ @hash[key] = dest
61
+ @hash_reverse.delete(src)
62
+ @hash_reverse[dest] = key
63
+ elsif @regexes_reverse.key?(src)
64
+ key = @regexes_reverse[src]
65
+ @regexes[rkey[0]] = [rkey[1], dest]
66
+ @regexes_reverse.delete(src)
67
+ @regexes_reverse[dest] = [rkey[0], rkey[1], dest]
68
+ end
69
+ end
70
+
71
+ def [](key)
72
+ @hash[key] || regex_lookup(key)
73
+ end
74
+
75
+ private
76
+ def regex_test
77
+ @regex_test ||= Regexp.new(@regexes.collect{|r| "(#{r[0]})"} * '|')
78
+ end
79
+
80
+ def regex_lookup(key)
81
+ if !@regexes.empty? && key.is_a?(String) && (data = regex_test.match(key))
82
+ (data_array = data.to_a).each_index do |i|
83
+ break @regexes[i].last if data_array.at(i+1)
84
+ end
85
+ end
86
+ end
87
+
88
+ end
@@ -0,0 +1,96 @@
1
+ require 'lib/fuzzy_hash'
2
+
3
+ describe "Fuzzy hash" do
4
+
5
+ it "should accept strings and retrieve based on them" do
6
+ l = FuzzyHash.new
7
+ l['asd'] = 'qwe'
8
+ l['asd'].should == 'qwe'
9
+ end
10
+
11
+ it "should accept regexs too" do
12
+ l = FuzzyHash.new
13
+ l[/asd.*/] = 'qwe'
14
+ l['asdqweasd'].should == 'qwe'
15
+ end
16
+
17
+ it "should prefer string to regex matches" do
18
+ l = FuzzyHash.new
19
+ l['asd'] = 'qwe2'
20
+ l[/asd.*/] = 'qwe'
21
+ l['asd'].should == 'qwe2'
22
+ end
23
+
24
+ it "should allow nil keys" do
25
+ l = FuzzyHash.new
26
+ l[nil] = 'qwe2'
27
+ l['asd'] = 'qwe'
28
+ l['asd'].should == 'qwe'
29
+ l[nil].should == 'qwe2'
30
+ end
31
+
32
+ it "should pick between the correct regex" do
33
+ hash = FuzzyHash.new
34
+ hash[/^\d+$/] = 'number'
35
+ hash[/.*/] = 'something'
36
+ hash['123asd'].should == 'something'
37
+ end
38
+
39
+ it "should be able to delete by value for hash" do
40
+ l = FuzzyHash.new
41
+ l[nil] = 'qwe2'
42
+ l['asd'] = 'qwe'
43
+ l['asd'].should == 'qwe'
44
+ l[nil].should == 'qwe2'
45
+ l.delete_value('qwe2')
46
+ l[nil].should == nil
47
+ end
48
+
49
+ it "should be able to delete by value for regex" do
50
+ l = FuzzyHash.new
51
+ l[/qwe.*/] = 'qwe2'
52
+ l['asd'] = 'qwe'
53
+ l['asd'].should == 'qwe'
54
+ l['qweasd'].should == 'qwe2'
55
+ l.delete_value('qwe2')
56
+ l['qweasd'].should == nil
57
+ end
58
+
59
+ it "should iterate through the keys" do
60
+ l = FuzzyHash.new
61
+ l[/qwe.*/] = 'qwe2'
62
+ l['asd'] = 'qwe'
63
+ l['zxc'] = 'qwe'
64
+ ([/qwe.*/,'asd','zxc'] & l.keys).size.should == 3
65
+ end
66
+
67
+ it "should iterate through the values" do
68
+ l = FuzzyHash.new
69
+ l[/qwe.*/] = 'qwe2'
70
+ l['asd'] = 'qwe'
71
+ l['zxc'] = 'qwelkj'
72
+ (['qwe2','qwe','qwelkj'] & l.values).size.should == 3
73
+ end
74
+
75
+ it "should clear" do
76
+ l = FuzzyHash.new
77
+ l[/qwe.*/] = 'qwe2'
78
+ l['asd'] = 'qwe'
79
+ l['zxc'] = 'qwelkj'
80
+ l.clear
81
+ l.empty?.should == true
82
+ end
83
+
84
+ it "should ==" do
85
+ l_1 = FuzzyHash.new
86
+ l_1[/qwe.*/] = 'qwe2'
87
+ l_1['asd'] = 'qwelkj'
88
+ l_1['zxc'] = 'qwe'
89
+ l_2 = FuzzyHash.new
90
+ l_2['zxc'] = 'qwe'
91
+ l_2['asd'] = 'qwelkj'
92
+ l_2[/qwe.*/] = 'qwe2'
93
+ l_1.should == l_2
94
+ end
95
+
96
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,7 @@
1
+ --colour
2
+ --format
3
+ specdoc
4
+ --loadby
5
+ mtime
6
+ --reverse
7
+ --backtrace
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: joshbuddy-fuzzy_hash
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Joshua Hull
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-26 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: A weird hash with special semantics for regex keys
17
+ email: joshbuddy@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ files:
25
+ - Manifest.txt
26
+ - Rakefile
27
+ - README.rdoc
28
+ - VERSION.yml
29
+ - lib/fuzzy_hash.rb
30
+ - spec/fuzzy_hash_spec.rb
31
+ - spec/spec.opts
32
+ has_rdoc: true
33
+ homepage: http://github.com/joshbuddy/fuzzy_hash
34
+ post_install_message:
35
+ rdoc_options:
36
+ - --inline-source
37
+ - --charset=UTF-8
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: "0"
45
+ version:
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ version:
52
+ requirements: []
53
+
54
+ rubyforge_project:
55
+ rubygems_version: 1.2.0
56
+ signing_key:
57
+ specification_version: 2
58
+ summary: A weird hash with special semantics for regex keys
59
+ test_files: []
60
+