hashery 1.5.0 → 2.0.0

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.
Files changed (70) hide show
  1. data/.ruby +30 -17
  2. data/.yardopts +1 -0
  3. data/Config.rb +28 -0
  4. data/{QED.rdoc → DEMO.rdoc} +0 -0
  5. data/HISTORY.rdoc +37 -0
  6. data/LICENSE.txt +26 -0
  7. data/NOTICE.txt +46 -0
  8. data/README.rdoc +10 -7
  9. data/lib/hashery.rb +6 -6
  10. data/lib/hashery.yml +30 -17
  11. data/lib/hashery/association.rb +169 -109
  12. data/lib/hashery/casting_hash.rb +128 -135
  13. data/lib/hashery/core_ext.rb +89 -61
  14. data/lib/hashery/crud_hash.rb +365 -0
  15. data/lib/hashery/dictionary.rb +545 -345
  16. data/lib/hashery/fuzzy_hash.rb +177 -125
  17. data/lib/hashery/ini_hash.rb +321 -0
  18. data/lib/hashery/key_hash.rb +54 -179
  19. data/lib/hashery/linked_list.rb +245 -191
  20. data/lib/hashery/lru_hash.rb +292 -202
  21. data/lib/hashery/open_cascade.rb +133 -78
  22. data/lib/hashery/open_hash.rb +127 -61
  23. data/lib/hashery/ordered_hash.rb +128 -122
  24. data/lib/hashery/path_hash.rb +238 -0
  25. data/lib/hashery/property_hash.rb +144 -80
  26. data/lib/hashery/query_hash.rb +85 -29
  27. data/lib/hashery/stash.rb +7 -3
  28. data/lib/hashery/static_hash.rb +46 -41
  29. data/test/case_association.rb +65 -4
  30. data/test/case_dictionary.rb +149 -5
  31. data/test/{case_keyhash.rb → case_key_hash.rb} +20 -14
  32. data/test/case_lru_hash.rb +162 -0
  33. data/test/{case_opencascade.rb → case_open_cascade.rb} +4 -8
  34. data/test/case_open_hash.rb +87 -0
  35. data/test/case_query_hash.rb +226 -0
  36. data/test/helper.rb +8 -0
  37. metadata +33 -63
  38. data/COPYING.rdoc +0 -45
  39. data/lib/hashery/basic_object.rb +0 -74
  40. data/lib/hashery/basic_struct.rb +0 -288
  41. data/lib/hashery/basicobject.rb +0 -1
  42. data/lib/hashery/basicstruct.rb +0 -1
  43. data/lib/hashery/castinghash.rb +0 -1
  44. data/lib/hashery/fuzzyhash.rb +0 -1
  45. data/lib/hashery/ini.rb +0 -268
  46. data/lib/hashery/keyhash.rb +0 -1
  47. data/lib/hashery/linkedlist.rb +0 -1
  48. data/lib/hashery/lruhash.rb +0 -1
  49. data/lib/hashery/memoizer.rb +0 -64
  50. data/lib/hashery/open_object.rb +0 -1
  51. data/lib/hashery/opencascade.rb +0 -1
  52. data/lib/hashery/openhash.rb +0 -1
  53. data/lib/hashery/openobject.rb +0 -1
  54. data/lib/hashery/orderedhash.rb +0 -1
  55. data/lib/hashery/ostructable.rb +0 -186
  56. data/lib/hashery/propertyhash.rb +0 -1
  57. data/lib/hashery/queryhash.rb +0 -1
  58. data/lib/hashery/statichash.rb +0 -1
  59. data/qed/01_openhash.rdoc +0 -57
  60. data/qed/02_queryhash.rdoc +0 -21
  61. data/qed/03_castinghash.rdoc +0 -13
  62. data/qed/04_statichash.rdoc +0 -22
  63. data/qed/05_association.rdoc +0 -59
  64. data/qed/06_opencascade.rdoc +0 -58
  65. data/qed/07_fuzzyhash.rdoc +0 -141
  66. data/qed/08_properyhash.rdoc +0 -38
  67. data/qed/09_ostructable.rdoc +0 -56
  68. data/qed/applique/ae.rb +0 -1
  69. data/test/case_basicstruct.rb +0 -192
  70. data/test/case_openhash.rb +0 -22
@@ -1,165 +1,158 @@
1
- # CastingHash is just like Hash, except that all keys and values
2
- # are passed through casting procedures.
3
- #--
4
- # TODO: Handle default_proc.
5
- #++
6
- class CastingHash < Hash
1
+ require 'hashery/crud_hash'
7
2
 
8
- # Default key conversion procedure.
9
- KEY_PROC = lambda{ |x| x } #.to_s }
10
-
11
- # Default value conversion procedure.
12
- VAL_PROC = lambda{ |x| x }
13
-
14
- #
15
- def self.[](hash)
16
- s = new
17
- hash.each{ |k,v| s[k] = v }
18
- s
19
- end
20
-
21
- #
22
- def initialize(hash={}, value_cast=nil, &key_cast)
23
- @key_proc = (key_cast || KEY_PROC)
24
- @value_proc = (value_cast || VAL_PROC).to_proc
25
- hash.each{ |k,v| self[k] = v }
26
- end
3
+ module Hashery
27
4
 
5
+ # CastingHash is just like CRUDHash, except that both keys and values
6
+ # can be passed through casting procedures.
28
7
  #
29
- def key_proc
30
- @key_proc
31
- end
8
+ class CastingHash < CRUDHash
32
9
 
33
- #
34
- def key_proc=(proc)
35
- @key_proc = proc.to_proc
36
- end
10
+ #
11
+ # Like `#new` but can take a priming Hash or Array-pairs.
12
+ #
13
+ # hash - Hash-like object.
14
+ #
15
+ # Examples
16
+ #
17
+ # CastingHash[:a,1,:b,2]
18
+ #
19
+ # Returns `CastingHash`.
20
+ #
21
+ def self.[](hash)
22
+ s = new
23
+ hash.each{ |k,v| s[k] = v }
24
+ s
25
+ end
37
26
 
38
- #
39
- def value_proc
40
- @value_proc
41
- end
27
+ #
28
+ # Unlike traditional Hash a CastingHash's block argument
29
+ # coerces key/value pairs when #store is called.
30
+ #
31
+ # default - Default value.
32
+ # cast_proc - Casting procedure.
33
+ #
34
+ def initialize(default=nil, &cast_proc)
35
+ @cast_proc = cast_proc
36
+ super(default, &nil)
37
+ end
42
38
 
43
- #
44
- def value_proc=(proc)
45
- @value_proc = proc.to_proc
46
- end
39
+ #
40
+ # The cast procedure.
41
+ #
42
+ # proc - Casting procedure.
43
+ #
44
+ # Returns `Proc` used for casting.
45
+ #
46
+ def cast_proc(&proc)
47
+ @cast_proc = proc if proc
48
+ @cast_proc
49
+ end
47
50
 
48
- #
49
- def [](k)
50
- super(key_proc[k])
51
- end
51
+ #
52
+ # Set `cast_proc`. This procedure must take two arguments (`key, value`)
53
+ # and return the same.
54
+ #
55
+ # proc - Casting procedure.
56
+ #
57
+ # Returns +proc+.
58
+ #
59
+ def cast_proc=(proc)
60
+ raise ArgumentError unless Proc === proc or NilClass === proc
61
+ @cast_proc = proc
62
+ end
52
63
 
53
- #
54
- def []=(k,v)
55
- super(key_proc[k], value_proc[v])
56
- end
64
+ #
65
+ # CRUD method for create and update. Unlike the parent class
66
+ # the key, value pair are passed threw the cast_proc before
67
+ # being set in the underlying hash table.
68
+ #
69
+ # key - Key of entry.
70
+ # value - Value of entry.
71
+ #
72
+ # Returns the +value+.
73
+ #
74
+ def store(key, value)
75
+ super(*cast_pair(key, value))
76
+ end
57
77
 
58
- #
59
- def <<(other)
60
- case other
61
- when Hash
62
- super(cast(other))
63
- when Array
64
- self[other[0]] = other[1]
65
- else
66
- raise ArgumentError
78
+ #
79
+ # Replace current entries with those from another Hash,
80
+ # or Hash-like object. Each entry is run through the
81
+ # casting procedure as it is added.
82
+ #
83
+ # other - Hash-like object.
84
+ #
85
+ # Returns +self+.
86
+ #
87
+ def replace(other)
88
+ super cast(other)
67
89
  end
68
- end
69
90
 
70
- def fetch(k)
71
- super(key_proc[k])
72
- end
91
+ #
92
+ # Convert the CastingHash to a regular Hash.
93
+ #
94
+ # Returns an ordinary `Hash`.
95
+ #
96
+ def to_hash
97
+ h = {}; each{ |k,v| h[k] = v }; h
98
+ end
73
99
 
74
- #
75
- def store(k, v)
76
- super(key_proc[k], value_proc[v])
77
- end
100
+ #
101
+ # Returns an ordinary `Hash`.
102
+ #
103
+ alias_method :to_h, :to_hash
78
104
 
79
- #
80
- def key?(k)
81
- super(key_proc[k])
82
- end
105
+ #
106
+ # Recast all entries via the cast procedure.
107
+ #
108
+ # TODO: Isn't this the same as `#rehash`?
109
+ #
110
+ # Returns +self+.
111
+ #
112
+ def recast!
113
+ replace self
114
+ end
83
115
 
84
- #
85
- def has_key?(k)
86
- super(key_proc[k])
87
- end
116
+ private
88
117
 
89
- # Synonym for Hash#rekey, but modifies the receiver in place (and returns it).
90
- #
91
- # foo = { :name=>'Gavin', :wife=>:Lisa }.to_stash
92
- # foo.rekey!{ |k| k.upcase } #=> { "NAME"=>"Gavin", "WIFE"=>:Lisa }
93
- # foo.inspect #=> { "NAME"=>"Gavin", "WIFE"=>:Lisa }
94
- #
95
- def rekey!(*args, &block)
96
- # for backward comptability (DEPRECATE?).
97
- block = args.pop.to_sym.to_proc if args.size == 1
98
- if args.empty?
99
- block = lambda{|k| k} unless block
100
- keys.each do |k|
101
- nk = block[k]
102
- self[nk] = delete(k) #if nk
118
+ #
119
+ # If `cast_proc` is defined then use it to process key-value pair,
120
+ # otherwise return them as is.
121
+ #
122
+ # key - Key of entry.
123
+ # value - Value of entry.
124
+ #
125
+ # Returns `Array` of key-value pair.
126
+ #
127
+ def cast_pair(key, value)
128
+ if cast_proc
129
+ return cast_proc.call(key, value)
130
+ else
131
+ return key, value
103
132
  end
104
- else
105
- raise ArgumentError, "3 for 2" if block
106
- to, from = *args
107
- self[to] = delete(from) if has_key?(from)
108
133
  end
109
- self
110
- end
111
-
112
- #
113
- def rekey(*args, &block)
114
- dup.rekey!(*args, &block)
115
- end
116
-
117
- #
118
- def delete(k)
119
- super(key_proc[k])
120
- end
121
-
122
- #
123
- def update(other)
124
- super(cast(other))
125
- end
126
-
127
- # Same as #update.
128
- def merge!(other)
129
- super(cast(other))
130
- end
131
-
132
- #
133
- def replace(other)
134
- super(cast(other))
135
- end
136
-
137
- #
138
- def values_at(*keys)
139
- super(keys.map(&key_proc))
140
- end
141
-
142
- #
143
- def to_hash
144
- h = {}; each{ |k,v| h[k] = v }; h
145
- end
146
-
147
- #
148
- alias_method :to_h, :to_hash
149
-
150
- private
151
134
 
135
+ #
136
+ # Cast a given +hash+ according to the `#key_proc` and `#value_proc`.
137
+ #
138
+ # hash - A `Hash` or anything the responds to `#each` like a hash.
139
+ #
140
+ # Returns a recasted `Hash`.
152
141
  #
153
142
  def cast(hash)
154
- h
143
+ h = {}
155
144
  hash.each do |k,v|
156
- h[key_proc[k]] = value_proc[v]
145
+ k, v = cast_pair(k, v)
146
+ h[k] = v
157
147
  end
158
148
  h
159
149
  end
160
150
 
151
+ end
152
+
161
153
  end
162
154
 
155
+ # TODO: Should we add #to_casting_hash to Hash classs?
163
156
 
164
157
  #class Hash
165
158
  #
@@ -1,82 +1,110 @@
1
- module Hashery
1
+ class Hash
2
2
 
3
- # This module is included into Ruby's core Hash class.
4
3
  #
5
- # These method derive from Ruby Facets.
6
- module CoreExt
4
+ # Create a hash given an `initial_hash`.
5
+ #
6
+ # initial_hash - Hash or hash-like object to use as priming data.
7
+ # block - Procedure used by initialize (e.g. default_proc).
8
+ #
9
+ # Returns a `Hash`.
10
+ #
11
+ def self.create(initial_hash={}, &block)
12
+ o = new &block
13
+ o.update(initial_hash)
14
+ o
15
+ end
7
16
 
8
- #
9
- def to_h
10
- self
11
- end
17
+ #
18
+ # Alias for `#[]`.
19
+ #
20
+ alias :read :[]
12
21
 
13
- #
14
- def to_hash
15
- self
16
- end
22
+ #
23
+ # Convert to Hash.
24
+ #
25
+ def to_hash
26
+ dup # -or- `h = {}; each{ |k,v| h[k] = v }; h` ?
27
+ end
17
28
 
18
- # Synonym for Hash#rekey, but modifies the receiver in place (and returns it).
19
- #
20
- # foo = { :name=>'Gavin', :wife=>:Lisa }
21
- # foo.rekey!{ |k| k.to_s } #=> { "name"=>"Gavin", "wife"=>:Lisa }
22
- # foo.inspect #=> { "name"=>"Gavin", "wife"=>:Lisa }
23
- #
24
- def rekey(key_map=nil, &block)
25
- if !(key_map or block)
26
- block = lambda{|k| k.to_sym}
27
- end
29
+ #
30
+ # For a Hash, `#to_h` is the same as `#to_hash`.
31
+ #
32
+ alias :to_h :to_hash
33
+
34
+ #
35
+ # Synonym for Hash#rekey, but modifies the receiver in place (and returns it).
36
+ #
37
+ # key_map - Hash of old key to new key.
38
+ # block - Procedure to convert keys, which can take just the key
39
+ # or both key and value as arguments.
40
+ #
41
+ # Examples
42
+ #
43
+ # foo = { :name=>'Gavin', :wife=>:Lisa }
44
+ # foo.rekey!{ |k| k.to_s } #=> { "name"=>"Gavin", "wife"=>:Lisa }
45
+ # foo.inspect #=> { "name"=>"Gavin", "wife"=>:Lisa }
46
+ #
47
+ # Returns `Hash`.
48
+ #
49
+ def rekey(key_map=nil, &block)
50
+ if !(key_map or block)
51
+ block = lambda{|k| k.to_sym}
52
+ end
28
53
 
29
- key_map ||= {}
54
+ key_map ||= {}
30
55
 
31
- hash = {}
56
+ hash = {}
32
57
 
33
- (keys - key_map.keys).each do |key|
34
- hash[key] = self[key]
35
- end
58
+ (keys - key_map.keys).each do |key|
59
+ hash[key] = self[key]
60
+ end
36
61
 
37
- key_map.each do |from, to|
38
- hash[to] = self[from] if key?(from)
39
- end
62
+ key_map.each do |from, to|
63
+ hash[to] = self[from] if key?(from)
64
+ end
40
65
 
41
- hash2 = {}
66
+ hash2 = {}
42
67
 
43
- if block
44
- if block.arity == 1 # TODO: is this condition needed?
45
- hash.each do |k, v|
46
- nk = block[k]
47
- #nk = (NA == nk ? k : nk) # TODO: Can't support this here.
48
- hash2[nk] = v
49
- end
50
- else
51
- hash.each do |k, v|
52
- nk = block[k,v]
53
- #nk = (NA == nk ? k : nk) # TODO:
54
- hash2[nk] = v
55
- end
68
+ if block
69
+ case block.arity
70
+ when 0
71
+ raise ArgumentError, "arity of 0 for #{block.inspect}"
72
+ when 2
73
+ hash.each do |k,v|
74
+ nk = block.call(k,v)
75
+ hash2[nk] = v
56
76
  end
57
77
  else
58
- hash2 = hash
78
+ hash.each do |k,v|
79
+ nk = block[k]
80
+ hash2[nk] = v
81
+ end
59
82
  end
60
-
61
- hash2
83
+ else
84
+ hash2 = hash
62
85
  end
63
86
 
64
- # Synonym for Hash#rekey, but modifies the receiver in place (and returns it).
65
- #
66
- # foo = { :name=>'Gavin', :wife=>:Lisa }
67
- # foo.rekey!{ |k| k.to_s } #=> { "name"=>"Gavin", "wife"=>:Lisa }
68
- # foo #=> { "name"=>"Gavin", "wife"=>:Lisa }
69
- #
70
- # CREDIT: Trans, Gavin Kistner
71
-
72
- def rekey!(key_map=nil, &block)
73
- replace(rekey(key_map, &block))
74
- end
87
+ hash2
88
+ end
75
89
 
90
+ #
91
+ # Synonym for Hash#rekey, but modifies the receiver in place (and returns it).
92
+ #
93
+ # key_map - Hash of old key to new key.
94
+ # block - Procedure to convert keys, which can take just the key
95
+ # or both key and value as arguments.
96
+ #
97
+ # Examples
98
+ #
99
+ # foo = { :name=>'Gavin', :wife=>:Lisa }
100
+ # foo.rekey!{ |k| k.to_s } #=> { "name"=>"Gavin", "wife"=>:Lisa }
101
+ # foo #=> { "name"=>"Gavin", "wife"=>:Lisa }
102
+ #
103
+ # Returns `Hash`.
104
+ #
105
+ def rekey!(key_map=nil, &block)
106
+ replace(rekey(key_map, &block))
76
107
  end
77
108
 
78
109
  end
79
110
 
80
- class Hash #:nodoc:
81
- include Hashery::CoreExt
82
- end