hashery 1.5.0 → 2.0.0

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