hashery 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/.ruby +57 -92
  2. data/.yardopts +8 -0
  3. data/COPYING.rdoc +45 -0
  4. data/HISTORY.rdoc +18 -0
  5. data/QED.rdoc +1 -0
  6. data/README.rdoc +42 -16
  7. data/lib/hashery.rb +16 -9
  8. data/lib/hashery.yml +57 -92
  9. data/lib/hashery/association.rb +3 -1
  10. data/lib/hashery/basic_object.rb +74 -0
  11. data/lib/hashery/basic_struct.rb +288 -1
  12. data/lib/hashery/basicobject.rb +1 -74
  13. data/lib/hashery/basicstruct.rb +1 -280
  14. data/lib/hashery/casting_hash.rb +171 -1
  15. data/lib/hashery/castinghash.rb +1 -171
  16. data/lib/hashery/core_ext.rb +82 -0
  17. data/lib/hashery/dictionary.rb +3 -0
  18. data/lib/hashery/fuzzy_hash.rb +154 -1
  19. data/lib/hashery/fuzzyhash.rb +1 -154
  20. data/lib/hashery/ini.rb +3 -2
  21. data/lib/hashery/key_hash.rb +186 -0
  22. data/lib/hashery/keyhash.rb +1 -0
  23. data/lib/hashery/linked_list.rb +195 -1
  24. data/lib/hashery/linkedlist.rb +1 -195
  25. data/lib/hashery/lru_hash.rb +273 -1
  26. data/lib/hashery/lruhash.rb +1 -273
  27. data/lib/hashery/open_cascade.rb +99 -1
  28. data/lib/hashery/open_hash.rb +77 -1
  29. data/lib/hashery/opencascade.rb +1 -99
  30. data/lib/hashery/openhash.rb +1 -77
  31. data/lib/hashery/ordered_hash.rb +168 -1
  32. data/lib/hashery/orderedhash.rb +1 -167
  33. data/lib/hashery/property_hash.rb +97 -1
  34. data/lib/hashery/propertyhash.rb +1 -97
  35. data/lib/hashery/query_hash.rb +35 -1
  36. data/lib/hashery/queryhash.rb +1 -35
  37. data/lib/hashery/stash.rb +3 -174
  38. data/lib/hashery/static_hash.rb +48 -1
  39. data/lib/hashery/statichash.rb +1 -48
  40. data/qed/06_opencascade.rdoc +12 -12
  41. data/test/case_association.rb +29 -15
  42. data/test/case_basicstruct.rb +192 -0
  43. data/test/case_dictionary.rb +149 -109
  44. data/test/case_keyhash.rb +175 -0
  45. data/test/case_opencascade.rb +89 -43
  46. data/test/case_openhash.rb +15 -11
  47. metadata +85 -78
  48. data/LICENSE +0 -206
  49. data/NOTICE +0 -11
  50. data/lib/hashery/sparse_array.rb +0 -1
  51. data/lib/hashery/sparsearray.rb +0 -577
  52. data/test/case_openobject.rb +0 -130
  53. data/test/case_sparsearray.rb +0 -316
  54. data/test/case_stash.rb +0 -131
@@ -1,280 +1 @@
1
- require 'hashery/basicobject'
2
-
3
- #require 'facets/hash/to_h'
4
- #require 'facets/kernel/object_class'
5
- #require 'facets/kernel/object_hexid'
6
-
7
- # = BasicStruct
8
- #
9
- # BasicObject is very similar to Ruby's own OpenStruct, but it offers some
10
- # advantages. With OpenStruct, slots with the same name as predefined
11
- # Object methods cannot be used. With BasicObject, almost any slot can be
12
- # defined. BasicObject is a subclass of BasicObject to ensure all method
13
- # slots, except those that are absolutely essential, are open for use.
14
- #
15
- #--
16
- # If you wish to pass an BasicObject to a routine that normal takes a Hash,
17
- # but are uncertain it can handle the distictions properly you can convert
18
- # easily to a Hash using #as_hash! and the result will automatically be
19
- # converted back to an BasicObject on return.
20
- #
21
- # o = BasicObject.new(:a=>1,:b=>2)
22
- # o.as_hash!{ |h| h.update(:a=>6) }
23
- # o #=> #<BasicObject {:a=>6,:b=>2}>
24
- #++
25
- #
26
- # Unlike a Hash, all BasicObject's keys are symbols and all keys are converted
27
- # to such using #to_sym on the fly.
28
-
29
- class BasicStruct < BasicObject
30
-
31
- #PUBLIC_METHODS = /(^__|^instance_|^object_|^\W|^as$|^send$|^class$|\?$)/
32
- #protected(*public_instance_methods.select{ |m| m !~ PUBLIC_METHODS })
33
-
34
- def self.[](hash=nil)
35
- new(hash)
36
- end
37
-
38
- # Inititalizer for BasicObject is slightly different than that of Hash.
39
- # It does not take a default parameter, but an initial priming Hash,
40
- # like OpenStruct. The initializer can still take a default block
41
- # however. To set the default value use <code>#default!(value)</code>.
42
- #
43
- # BasicObject.new(:a=>1).default!(0)
44
- #
45
- def initialize(hash=nil, &yld)
46
- @table = Hash.new(&yld)
47
- if hash
48
- hash.each{ |k,v| store(k,v) }
49
- end
50
- end
51
-
52
- #
53
- def initialize_copy(orig)
54
- orig.each{ |k,v| store(k,v) }
55
- end
56
-
57
- # Object inspection.
58
- # TODO: Need to get __class__ and __id__ in hex form.
59
- def inspect
60
- #@table.inspect
61
- hexid = __id__
62
- klass = "BasicObject" # __class__
63
- "#<#{klass}:#{hexid} #{@table.inspect}>"
64
- end
65
-
66
- # Convert to an associative array.
67
- def to_a
68
- @table.to_a
69
- end
70
-
71
- #
72
- def to_h
73
- @table.dup
74
- end
75
-
76
- #
77
- def to_hash
78
- @table.dup
79
- end
80
-
81
- #
82
- def to_basicstruct
83
- self
84
- end
85
-
86
- # Convert to an assignment procedure.
87
- def to_proc(response=false)
88
- hash = @table
89
- if response
90
- lambda do |o|
91
- hash.each do |k,v|
92
- o.__send__("#{k}=", v) rescue nil
93
- end
94
- end
95
- else
96
- lambda do |o|
97
- hash.each{ |k,v| o.__send__("#{k}=", v) }
98
- end
99
- end
100
- end
101
-
102
- # NOT SURE ABOUT THIS
103
- def as_hash
104
- @table
105
- end
106
-
107
- # Is a given +key+ defined?
108
- def key?(key)
109
- @table.key?(key.to_sym)
110
- end
111
-
112
- #
113
- def is_a?(klass)
114
- return true if klass == Hash # TODO: Is this wise? How to fake a subclass?
115
- return true if klass == BasicObject
116
- false
117
- end
118
-
119
- # Iterate over each key-value pair.
120
- def each(&yld)
121
- @table.each(&yld)
122
- end
123
-
124
- # Set the default value.
125
- def default!(default)
126
- @table.default = default
127
- end
128
-
129
- # Check equality.
130
- def ==( other )
131
- case other
132
- when BasicObject
133
- @table == other.as_hash
134
- when Hash
135
- @table == other
136
- else
137
- if other.respond_to?(:to_hash)
138
- @table == other.to_hash
139
- else
140
- false
141
- end
142
- end
143
- end
144
-
145
- #
146
- def eql?( other )
147
- case other
148
- when BasicObject
149
- @table.eql?(other.as_hash)
150
- else
151
- false
152
- end
153
- end
154
-
155
- #
156
- def <<(x)
157
- case x
158
- when Hash
159
- @table.update(x)
160
- when Array
161
- x.each_slice(2) do |(k,v)|
162
- @table[k] = v
163
- end
164
- end
165
- end
166
-
167
- #
168
- def []=(key, value)
169
- @table[key.to_sym] = value
170
- end
171
-
172
- #
173
- def [](key)
174
- @table[key.to_sym]
175
- end
176
-
177
- #
178
- def merge!(other)
179
- BasicObject.new(@table.merge!(other))
180
- end
181
-
182
- #
183
- def update!(other)
184
- @table.update(other)
185
- self
186
- end
187
-
188
- protected
189
-
190
- def store(k, v)
191
- @table.store(k.to_sym, v)
192
- end
193
-
194
- def fetch(k, *d, &b)
195
- @table.fetch(k.to_sym, *d, &b)
196
- end
197
-
198
- #def as_hash!
199
- # Functor.new do |op,*a,&b|
200
- # result = @table.__send__(op,*a,&b)
201
- # case result
202
- # when Hash
203
- # BasicObject.new(result)
204
- # else
205
- # result
206
- # end
207
- # end
208
- #end
209
-
210
- #def define_slot(key, value=nil)
211
- # @table[key.to_sym] = value
212
- #end
213
-
214
- #def protect_slot( key )
215
- # (class << self; self; end).class_eval {
216
- # protected key rescue nil
217
- # }
218
- #end
219
-
220
- def method_missing(sym, *args, &blk)
221
- type = sym.to_s[-1,1]
222
- key = sym.to_s.sub(/[=?!]$/,'').to_sym
223
- case type
224
- when '='
225
- store(key, args[0])
226
- when '!'
227
- @table.__send__(key, *args, &blk)
228
- # if key?(key)
229
- # fetch(key)
230
- # else
231
- # store(key, BasicObject.new)
232
- # end
233
- when '?'
234
- fetch(key)
235
- else
236
- fetch(key)
237
- end
238
- end
239
-
240
- end
241
-
242
- # Core Extensions
243
-
244
- class Hash
245
- # Convert a Hash into a BasicStruct.
246
- def to_basicstruct
247
- BasicStruct[self]
248
- end
249
- end
250
-
251
- =begin
252
- class NilClass
253
- # Nil converts to an empty BasicObject.
254
- def to_basicstruct
255
- BasicObject.new
256
- end
257
- end
258
-
259
- class Proc
260
- # Translates a Proc into an BasicObject. By droping an BasicObject into
261
- # the Proc, the resulting assignments incured as the procedure is
262
- # evaluated produce the BasicObject. This technique is simlar to that
263
- # of MethodProbe.
264
- #
265
- # p = lambda { |x|
266
- # x.word = "Hello"
267
- # }
268
- # o = p.to_basicstruct
269
- # o.word #=> "Hello"
270
- #
271
- # NOTE The Proc must have an arity of one --no more and no less.
272
- def to_basicstruct
273
- raise ArgumentError, 'bad arity for converting Proc to basicstruct' if arity != 1
274
- o = BasicObject.new
275
- self.call( o )
276
- o
277
- end
278
- end
279
- =end
280
-
1
+ require 'hashery/basic_struct'
@@ -1 +1,171 @@
1
- require 'hashery/castinghash'
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
7
+
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
27
+
28
+ #
29
+ def key_proc
30
+ @key_proc
31
+ end
32
+
33
+ #
34
+ def key_proc=(proc)
35
+ @key_proc = proc.to_proc
36
+ end
37
+
38
+ #
39
+ def value_proc
40
+ @value_proc
41
+ end
42
+
43
+ #
44
+ def value_proc=(proc)
45
+ @value_proc = proc.to_proc
46
+ end
47
+
48
+ #
49
+ def [](k)
50
+ super(key_proc[k])
51
+ end
52
+
53
+ #
54
+ def []=(k,v)
55
+ super(key_proc[k], value_proc[v])
56
+ end
57
+
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
67
+ end
68
+ end
69
+
70
+ def fetch(k)
71
+ super(key_proc[k])
72
+ end
73
+
74
+ #
75
+ def store(k, v)
76
+ super(key_proc[k], value_proc[v])
77
+ end
78
+
79
+ #
80
+ def key?(k)
81
+ super(key_proc[k])
82
+ end
83
+
84
+ #
85
+ def has_key?(k)
86
+ super(key_proc[k])
87
+ end
88
+
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
103
+ 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
+ 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
+
152
+ #
153
+ def cast(hash)
154
+ h
155
+ hash.each do |k,v|
156
+ h[key_proc[k]] = value_proc[v]
157
+ end
158
+ h
159
+ end
160
+
161
+ end
162
+
163
+
164
+ #class Hash
165
+ #
166
+ # # Convert a Hash to a CastingHash.
167
+ # def to_casting_hash(value_cast=nil, &key_cast)
168
+ # CastingHash.new(self, value_cast, &key_cast)
169
+ # end
170
+ #
171
+ #end