fuzzy_hash 0.0.3

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,63 @@
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
+ s.rubyforge_project = 'fuzzyhash' # This line would be new
11
+ end
12
+ rescue LoadError
13
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
14
+ end
15
+
16
+ # These are new tasks
17
+ begin
18
+ require 'rake/contrib/sshpublisher'
19
+ namespace :rubyforge do
20
+
21
+ desc "Release gem and RDoc documentation to RubyForge"
22
+ task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
23
+
24
+ namespace :release do
25
+ desc "Publish RDoc to RubyForge."
26
+ task :docs => [:rdoc] do
27
+ config = YAML.load(
28
+ File.read(File.expand_path('~/.rubyforge/user-config.yml'))
29
+ )
30
+
31
+ host = "#{config['username']}@rubyforge.org"
32
+ remote_dir = "/var/www/gforge-projects/fuzzyhash/"
33
+ local_dir = 'rdoc'
34
+
35
+ Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
36
+ end
37
+ end
38
+ end
39
+ rescue LoadError
40
+ puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
41
+ end
42
+
43
+
44
+ require 'spec'
45
+ require 'spec/rake/spectask'
46
+ task :spec => 'spec:all'
47
+ namespace(:spec) do
48
+ Spec::Rake::SpecTask.new(:all) do |t|
49
+ t.spec_opts ||= []
50
+ t.spec_opts << "-rubygems"
51
+ t.spec_opts << "--options" << "spec/spec.opts"
52
+ t.spec_files = FileList['spec/**/*_spec.rb']
53
+ end
54
+
55
+ end
56
+
57
+ desc "Run all examples with RCov"
58
+ Spec::Rake::SpecTask.new('spec_with_rcov') do |t|
59
+ t.spec_files = FileList['spec/**/*.rb']
60
+ t.rcov = true
61
+ t.rcov_opts = ['--exclude', 'spec']
62
+ end
63
+
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :patch: 3
3
+ :major: 0
4
+ :minor: 0
data/lib/fuzzy_hash.rb ADDED
@@ -0,0 +1,87 @@
1
+ class FuzzyHash
2
+
3
+ def initialize(init_hash = nil)
4
+ @regexes = []
5
+ @hash_reverse = {}
6
+ @regexes_reverse = {}
7
+ @hash = {}
8
+ init_hash.each{ |key,value| self[key] = value } if init_hash
9
+ end
10
+
11
+ def clear
12
+ @hash.clear
13
+ @regexes.clear
14
+ @hash_reverse.clear
15
+ @regexes_reverse.clear
16
+ end
17
+
18
+ def ==(o)
19
+ o.instance_variable_get(:@hash) == @hash &&
20
+ o.instance_variable_get(:@regexes) == @regexes
21
+ end
22
+
23
+ def empty?
24
+ @hash.empty? && @regexes.empty?
25
+ end
26
+
27
+ def keys
28
+ @hash.keys + @regexes.collect{|r| r.first}
29
+ end
30
+
31
+ def values
32
+ @hash.values + @regexes.collect{|r| r.last}
33
+ end
34
+
35
+ def each
36
+ @hash.each{|k,v| yield k,v }
37
+ @regexes.each{|v| yield v.first, v.last }
38
+ end
39
+
40
+ def delete_value(value)
41
+ @hash.delete(@hash_reverse[value]) || ((rr = @regexes_reverse[value]) && @regexes.delete_at(rr[0]))
42
+ end
43
+
44
+ def []=(key, value)
45
+ case key
46
+ when Regexp
47
+ @regexes << [key, value]
48
+ @regex_test = nil
49
+ @regexes_reverse[value] = [@regexes.size - 1, key, value]
50
+ else
51
+ @hash[key] = value
52
+ @hash_reverse[value] = key
53
+ end
54
+ end
55
+
56
+ def replace(src, dest)
57
+ if @hash_reverse.key?(src)
58
+ key = @hash_reverse[src]
59
+ @hash[key] = dest
60
+ @hash_reverse.delete(src)
61
+ @hash_reverse[dest] = key
62
+ elsif @regexes_reverse.key?(src)
63
+ key = @regexes_reverse[src]
64
+ @regexes[rkey[0]] = [rkey[1], dest]
65
+ @regexes_reverse.delete(src)
66
+ @regexes_reverse[dest] = [rkey[0], rkey[1], dest]
67
+ end
68
+ end
69
+
70
+ def [](key)
71
+ @hash.key?(key) ? @hash[key] : regex_lookup(key)
72
+ end
73
+
74
+ private
75
+ def regex_test
76
+ @regex_test ||= Regexp.new(@regexes.collect{|r| "(#{r[0]})"} * '|')
77
+ end
78
+
79
+ def regex_lookup(key)
80
+ if !@regexes.empty? && key.is_a?(String) && (data = regex_test.match(key))
81
+ (data_array = data.to_a).each_index do |i|
82
+ break @regexes[i].last if data_array.at(i+1)
83
+ end
84
+ end
85
+ end
86
+
87
+ end
@@ -0,0 +1,106 @@
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 allow boolean keys" do
33
+ l = FuzzyHash.new
34
+ l[false] = 'false'
35
+ l[true] = 'true'
36
+ l[/.*/] = 'everything else'
37
+ l[true].should == 'true'
38
+ l[false].should == 'false'
39
+ l['false'].should == 'everything else'
40
+ end
41
+
42
+ it "should pick between the correct regex" do
43
+ hash = FuzzyHash.new
44
+ hash[/^\d+$/] = 'number'
45
+ hash[/.*/] = 'something'
46
+ hash['123asd'].should == 'something'
47
+ end
48
+
49
+ it "should be able to delete by value for hash" do
50
+ l = FuzzyHash.new
51
+ l[nil] = 'qwe2'
52
+ l['asd'] = 'qwe'
53
+ l['asd'].should == 'qwe'
54
+ l[nil].should == 'qwe2'
55
+ l.delete_value('qwe2')
56
+ l[nil].should == nil
57
+ end
58
+
59
+ it "should be able to delete by value for regex" do
60
+ l = FuzzyHash.new
61
+ l[/qwe.*/] = 'qwe2'
62
+ l['asd'] = 'qwe'
63
+ l['asd'].should == 'qwe'
64
+ l['qweasd'].should == 'qwe2'
65
+ l.delete_value('qwe2')
66
+ l['qweasd'].should == nil
67
+ end
68
+
69
+ it "should iterate through the keys" do
70
+ l = FuzzyHash.new
71
+ l[/qwe.*/] = 'qwe2'
72
+ l['asd'] = 'qwe'
73
+ l['zxc'] = 'qwe'
74
+ ([/qwe.*/,'asd','zxc'] & l.keys).size.should == 3
75
+ end
76
+
77
+ it "should iterate through the values" do
78
+ l = FuzzyHash.new
79
+ l[/qwe.*/] = 'qwe2'
80
+ l['asd'] = 'qwe'
81
+ l['zxc'] = 'qwelkj'
82
+ (['qwe2','qwe','qwelkj'] & l.values).size.should == 3
83
+ end
84
+
85
+ it "should clear" do
86
+ l = FuzzyHash.new
87
+ l[/qwe.*/] = 'qwe2'
88
+ l['asd'] = 'qwe'
89
+ l['zxc'] = 'qwelkj'
90
+ l.clear
91
+ l.empty?.should == true
92
+ end
93
+
94
+ it "should ==" do
95
+ l_1 = FuzzyHash.new
96
+ l_1[/qwe.*/] = 'qwe2'
97
+ l_1['asd'] = 'qwelkj'
98
+ l_1['zxc'] = 'qwe'
99
+ l_2 = FuzzyHash.new
100
+ l_2['zxc'] = 'qwe'
101
+ l_2['asd'] = 'qwelkj'
102
+ l_2[/qwe.*/] = 'qwe2'
103
+ l_1.should == l_2
104
+ end
105
+
106
+ 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,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fuzzy_hash
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Joshua Hull
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-06-16 00:00:00 -04: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
+ - README.rdoc
27
+ - Rakefile
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
+ licenses: []
35
+
36
+ post_install_message:
37
+ rdoc_options:
38
+ - --charset=UTF-8
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ version:
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ requirements: []
54
+
55
+ rubyforge_project: fuzzyhash
56
+ rubygems_version: 1.3.4
57
+ signing_key:
58
+ specification_version: 3
59
+ summary: A weird hash with special semantics for regex keys
60
+ test_files:
61
+ - spec/fuzzy_hash_spec.rb