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,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