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,35 +1,91 @@
1
- # = QueryHash
2
- #
3
- # QueryHash is a similar to OpenHash. Like OpenHash,
4
- # entries can be assigned via setter methods, but
5
- # entries can only be looked up via query methods
6
- # (i.e. methods ending in a ?-mark), hence the name
7
- # of this class.
8
- #
9
- # A QueryHash is not quite as elegant as an OpenHash
10
- # in that reader methods must end in ?-marks, but
11
- # it remains fully compatible with Hash regardless
12
- # of it's settings.
13
-
14
- class QueryHash < Hash
15
-
16
- def to_h
17
- dup
18
- end
1
+ module Hashery
19
2
 
20
- def to_hash
21
- dup
22
- end
3
+ require 'hashery/key_hash'
4
+
5
+ # QueryHash is essentially a Hash class, but with some OpenStruct-like features.
6
+ #
7
+ # q = QueryHash.new
8
+ #
9
+ # Entries can be added to the Hash via a setter method.
10
+ #
11
+ # q.a = 1
12
+ #
13
+ # Then looked up via a query method.
14
+ #
15
+ # q.a? #=> 1
16
+ #
17
+ # The can also be looked up via a bang method.
18
+ #
19
+ # q.a! #=> 1
20
+ #
21
+ # The difference between query methods and bang methods is that the bang method
22
+ # will auto-instantiate the entry if not present, where as a query method will not.
23
+ #
24
+ # A QueryHash might not be quite as elegant as an OpenHash in that reader
25
+ # methods must end in `?` or `!`, but it remains fully compatible with Hash
26
+ # regardless of it's settings.
27
+ #
28
+ class QueryHash < CRUDHash
23
29
 
24
- def method_missing(s,*a,&b)
25
- case s.to_s
26
- when /\=$/
27
- self[s.to_s.chomp('=').to_sym] = a[0]
28
- when /\?$/
29
- self[s.to_s.chomp('?').to_sym]
30
- else
31
- super(s,*a,&b)
30
+ #
31
+ # By default the `key_proc` is set to convert all keys to strings via `#to_s`.
32
+ #
33
+ # default - Default object, or
34
+ # default_proc - Default procedure.
35
+ #
36
+ def initialize(*default, &default_proc)
37
+ @key_proc = Proc.new{ |k| k.to_s }
38
+ super(*default, &default_proc)
32
39
  end
40
+
41
+ #
42
+ # Route get and set calls.
43
+ #
44
+ # s - [Symbol] Name of method.
45
+ # a - [Array] Method arguments.
46
+ # b - [Proc] Block argument.
47
+ #
48
+ # Examples
49
+ #
50
+ # o = QueryHash.new
51
+ # o.a = 1
52
+ # o.a? #=> 1
53
+ # o.b? #=> nil
54
+ #
55
+ def method_missing(s,*a, &b)
56
+ type = s.to_s[-1,1]
57
+ name = s.to_s.sub(/[!?=]$/, '')
58
+ key = name #key = cast_key(name)
59
+
60
+ case type
61
+ when '='
62
+ store(key, a.first)
63
+ when '!'
64
+ default = (default_proc ? default_proc.call(self, key) : default)
65
+ key?(key) ? fetch(key) : store(key, default)
66
+ when '?'
67
+ key?(key) ? fetch(key) : nil
68
+ else
69
+ # return self[key] if key?(key)
70
+ super(s,*a,&b)
71
+ end
72
+ end
73
+
74
+ #
75
+ # Custom #respond_to to account for #method_missing.
76
+ #
77
+ # name - The method name to check.
78
+ #
79
+ # Returns `true` or `false`.
80
+ #
81
+ def respond_to?(name)
82
+ return true if name.to_s.end_with?('=')
83
+ return true if name.to_s.end_with?('?')
84
+ return true if name.to_s.end_with?('!')
85
+ #key?(name.to_sym) || super(name)
86
+ super(name)
87
+ end
88
+
33
89
  end
34
90
 
35
91
  end
@@ -1,10 +1,14 @@
1
- require 'hashery/keyhash'
1
+ require 'hashery/key_hash'
2
2
 
3
- Stash = KeyHash
3
+ module Hashery
4
+ # Stash is the original name for the KeyHash.
5
+ Stash = KeyHash
6
+ end
4
7
 
5
8
  class Hash
6
9
  # Convert Hash to Stash.
7
10
  def to_stash
8
- Stash[self]
11
+ Hashery::Stash[self]
9
12
  end
10
13
  end
14
+
@@ -1,48 +1,53 @@
1
- # = StaticHash
2
- #
3
- # A Hash object which raises an error if any
4
- # previously-defined key attempts to be set again.
5
- #
6
- # == Synopsis
7
- #
8
- # foo = StaticHash.new
9
- # foo['name'] = 'Tom' #=> 'Tom'
10
- # foo['age'] = 30 #=> 30
11
- # foo['name'] = 'Bob'
12
- #
13
- # _produces_
14
- #
15
- # ArgumentError: Duplicate key for StaticHash -- 'name'
16
- #
17
- # == Credit
18
- #
19
- # StaticHash has it's orgins in Gavin Kistner's WriteOnceHash
20
- # class found in his +basiclibrary.rb+ script.
1
+ module Hashery
21
2
 
22
- class StaticHash < Hash
23
-
24
- # Set a value for a key. Raises an error if that key already
25
- # exists with a different value.
3
+ # StaticHash ia a Hash object which raises an error if any
4
+ # previously-defined key attempts to be set again.
5
+ #
6
+ # foo = StaticHash.new
7
+ # foo['name'] = 'Tom' #=> 'Tom'
8
+ # foo['age'] = 30 #=> 30
9
+ # foo['name'] = 'Bob'
10
+ #
11
+ # produces
12
+ #
13
+ # ArgumentError: Duplicate key for StaticHash -- 'name'
14
+ #
15
+ # StaticHash has it's orgins in Gavin Kistner's WriteOnceHash
16
+ # class found in his +basiclibrary.rb+ script.
17
+ #
18
+ # TODO: Maybe StaticHash isn't bets name for this class?
19
+ #
20
+ class StaticHash < CRUDHash
26
21
 
27
- def []=(key, value)
28
- if key?(key) && self[key] != value
29
- raise ArgumentError, "Duplicate key for StaticHash -- #{key.inspect}"
22
+ #
23
+ # Set a value for a key. Raises an error if that key already
24
+ # exists with a different value.
25
+ #
26
+ # key - Index key to associate with value.
27
+ # value - Value to associate with key.
28
+ #
29
+ # Retruns value.
30
+ #
31
+ def store(key, value)
32
+ if key?(key) && read(key) != value
33
+ raise ArgumentError, "Duplicate key for StaticHash -- #{key.inspect}"
34
+ end
35
+ super(key, value)
30
36
  end
31
- super(key, value)
32
- end
33
37
 
34
- #
35
- def update(hash)
36
- dups = (keys | hash.keys)
37
- if dups.empty?
38
- super(hash)
39
- else
40
- raise ArgumentError, "Duplicate key for StaticHash -- #{dups.inspect}"
41
- end
42
- end
38
+ #
39
+ #def update(hash)
40
+ # dups = (keys | hash.keys)
41
+ # if dups.empty?
42
+ # super(hash)
43
+ # else
44
+ # raise ArgumentError, "Duplicate key for StaticHash -- #{dups.inspect}"
45
+ # end
46
+ #end
43
47
 
44
- #
45
- alias_method :merge!, :update
48
+ #
49
+ #alias_method :merge!, :update
46
50
 
47
- end
51
+ end
48
52
 
53
+ end
@@ -1,6 +1,6 @@
1
- require 'lemon'
2
- require 'ae'
1
+ require 'helper'
3
2
 
3
+ # must be required independently
4
4
  require 'hashery/association'
5
5
 
6
6
  testcase Association do
@@ -11,6 +11,28 @@ testcase Association do
11
11
  end
12
12
  end
13
13
 
14
+ class_method :[] do
15
+ test do
16
+ a = Association[:a, 1]
17
+ a.assert.index == :a
18
+ a.assert.value == 1
19
+ end
20
+ end
21
+
22
+ method :index do
23
+ test do
24
+ a = Association.new(:a,1)
25
+ a.index.assert == :a
26
+ end
27
+ end
28
+
29
+ method :value do
30
+ test do
31
+ a = Association.new(:a,1)
32
+ a.value.assert == 1
33
+ end
34
+ end
35
+
14
36
  method :to_ary do
15
37
  test do
16
38
  k,v = [],[]
@@ -28,13 +50,52 @@ testcase Association do
28
50
  end
29
51
  end
30
52
 
53
+ method :<=> do
54
+ test 'when differnt in value' do
55
+ a = Association.new(:a,1)
56
+ b = Association.new(:b,2)
57
+ (a <=> b).assert == -1
58
+ (b <=> a).assert == 1
59
+ end
60
+
61
+ test 'when equal value' do
62
+ a = Association.new(:a,1)
63
+ b = Association.new(:b,1)
64
+ (a <=> b).assert == 0
65
+ end
66
+ end
67
+
68
+ method :invert! do
69
+ test do
70
+ a = Association.new(:a,1)
71
+ a.invert!
72
+ a.index.assert == 1
73
+ a.value.assert == :a
74
+ end
75
+ end
76
+
77
+ method :inspect do
78
+ test do
79
+ a = Association.new(:a,1)
80
+ a.inspect.assert == ":a >> 1"
81
+ end
82
+ end
83
+
84
+ method :to_s do
85
+ test do
86
+ a = Association.new(:a,1)
87
+ a.to_s.assert == "a >> 1"
88
+ end
89
+ end
90
+
31
91
  end
32
92
 
33
93
  testcase Object do
34
94
  method :associations do
35
95
  test do
36
- complex = [ :a >> :b, :a >> :c ]
37
- :a.associations.assert == [ :b, :c ]
96
+ s = 'a'
97
+ complex = [ s >> :b, s >> :c ]
98
+ s.associations.assert == [:b, :c]
38
99
  end
39
100
  end
40
101
 
@@ -1,8 +1,4 @@
1
- require 'lemon'
2
- require 'ae'
3
- require 'ae/legacy'
4
-
5
- require 'hashery/dictionary'
1
+ require 'helper'
6
2
 
7
3
  testcase Dictionary do
8
4
  include AE::Legacy::Assertions
@@ -178,5 +174,153 @@ testcase Dictionary do
178
174
  end
179
175
  end
180
176
 
177
+ method :select do
178
+ test do
179
+ d = Dictionary[:a=>1, :b=>2, :c=>3]
180
+ r = d.select{ |k,v| v % 2 == 1 }
181
+ r.assert == [[:a, 1], [:c, 3]]
182
+ end
183
+ end
184
+
185
+ method :to_h do
186
+ test do
187
+ d = Dictionary[:a=>1, :b=>2]
188
+ h = d.to_h
189
+ h.assert == {:a=>1, :b=>2}
190
+ end
191
+ end
192
+
193
+ method :replace do
194
+ test do
195
+ d1 = Dictionary[:a=>1, :b=>2]
196
+ d2 = Dictionary[:c=>3, :d=>4]
197
+ d1.replace(d2)
198
+ d1.to_h.assert == {:c=>3, :d=>4}
199
+ end
200
+ end
201
+
202
+ method :reverse do
203
+ test do
204
+ d = Dictionary[:a=>1, :b=>2, :c=>3]
205
+ r = d.reverse
206
+ r.first.assert == 3
207
+ end
208
+ end
209
+
210
+ method :invert do
211
+ test do
212
+ d = Dictionary[:a=>1, :b=>2, :c=>3]
213
+ r = d.invert
214
+ Dictionary.assert === r
215
+ r.to_h.assert == {1=>:a, 2=>:b, 3=>:c}
216
+ end
217
+ end
218
+
219
+ method :each_key do
220
+ d = Dictionary[:a=>1, :b=>2, :c=>3]
221
+ a = []
222
+ d.each_key{ |k| a << k }
223
+ a.assert == [:a, :b, :c]
224
+ end
225
+
226
+ method :each_value do
227
+ d = Dictionary[:a=>1, :b=>2, :c=>3]
228
+ a = []
229
+ d.each_value{ |v| a << v }
230
+ a.assert == [1, 2, 3]
231
+ end
232
+
233
+ method :clear do
234
+ d = Dictionary[:a=>1, :b=>2, :c=>3]
235
+ d.clear
236
+ d.to_a.assert == []
237
+ end
238
+
239
+ method :fetch do
240
+ d = Dictionary[:a=>1, :b=>2, :c=>3]
241
+ d.fetch(:a).assert == 1
242
+ end
243
+
244
+ method :key? do
245
+ test do
246
+ d = Dictionary[:a=>1, :b=>2, :c=>3]
247
+ d.assert.key?(:a)
248
+ d.refute.key?(:d)
249
+ end
250
+ end
251
+
252
+ method :has_key? do
253
+ test do
254
+ d = Dictionary[:a=>1, :b=>2, :c=>3]
255
+ d.assert.has_key?(:a)
256
+ d.refute.has_key?(:d)
257
+ end
258
+ end
259
+
260
+ method :length do
261
+ test do
262
+ d = Dictionary[:a=>1, :b=>2, :c=>3]
263
+ d.length.assert == 3
264
+ end
265
+ end
266
+
267
+ method :to_a do
268
+ test do
269
+ d = Dictionary[:a=>1, :b=>2, :c=>3]
270
+ d.to_a.assert == [[:a,1], [:b,2], [:c,3]]
271
+ end
272
+ end
273
+
274
+ method :to_hash do
275
+ test do
276
+ d = Dictionary[:a=>1, :b=>2, :c=>3]
277
+ d.to_hash.assert == {:a=>1, :b=>2, :c=>3}
278
+ end
279
+ end
280
+
281
+ method :empty? do
282
+ test "is emtpy" do
283
+ d = Dictionary[]
284
+ d.assert.empty?
285
+ end
286
+
287
+ test 'is not emtpy' do
288
+ d = Dictionary[:a=>1, :b=>2, :c=>3]
289
+ d.refute.empty?
290
+ end
291
+ end
292
+
293
+ method :order_by_key do
294
+ test do
295
+ d = Dictionary[:b=>1, :c=>2, :a=>4]
296
+ d.order_by_key
297
+ d.order.assert == [:a, :b, :c]
298
+ end
299
+ end
300
+
301
+ method :order_by_value do
302
+ test do
303
+ d = Dictionary[:b=>1, :c=>2, :a=>4]
304
+ d.order_by_value
305
+ d.order.assert == [:b, :c, :a]
306
+ end
307
+ end
308
+
309
+ class_method :alpha do
310
+ test do
311
+ d = Dictionary.alpha
312
+ d.update(:b=>1, :c=>2, :a=>4)
313
+ d.order.assert == [:a, :b, :c]
314
+ end
315
+ end
316
+
317
+ class_method :auto do
318
+ test do
319
+ d = Dictionary.auto
320
+ s = d[:foo]
321
+ s.class.assert == Dictionary
322
+ end
323
+ end
324
+
181
325
  end
182
326