hashery 1.4.0 → 1.5.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 (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
@@ -7,7 +7,9 @@
7
7
  # link-lists, simple ordered maps and mixed collections,
8
8
  # among them.
9
9
  #
10
- # NOTE: This class is still fairly experimental.
10
+ # NOTE: This class is still fairly experimental. And it is not
11
+ # loaded along with the other Hashery libraries when using
12
+ # `require 'hashery'`.
11
13
  #
12
14
  # == Usage
13
15
  #
@@ -0,0 +1,74 @@
1
+ # Facets' BasicObject is an implementation of Jim Weirich's BlankSlate.
2
+ #
3
+ # BlankSlate
4
+ # Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
5
+ # All rights reserved.
6
+ #
7
+ # Since Ruby 1.9 has a BasicObject class this will of course be
8
+ # deprecated as 1.9 goes mainstream.
9
+
10
+ unless defined? BasicObject # in case it already exists!
11
+
12
+ # BasicObject provides an abstract base class with no predefined
13
+ # methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
14
+ # BlankSlate is useful as a base class when writing classes that
15
+ # depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
16
+ class BasicObject
17
+ class << self
18
+ # Hide the method named +name+ in the BlankSlate class. Don't
19
+ # hide +instance_eval+ or any method beginning with "__".
20
+ #
21
+ # According to 1.9.1 it should have only these methods:
22
+ #
23
+ # * #__send__
24
+ # * #instance_eval
25
+ # * #instance_exec
26
+ # * #equal?
27
+ # * #==
28
+ # * #!
29
+ # * #!=
30
+ # * respond_to?
31
+ #
32
+ # Seems to me it should have #__id__ too.
33
+ def hide(name)
34
+ undef_method name if
35
+ instance_methods.include?(name.to_s) and
36
+ name !~ /^(__|respond_to\?|instance_eval$|instance_exec$|equal\?$|\=\=$)/
37
+ end
38
+ end
39
+ instance_methods.each{ |m| hide(m) }
40
+ end
41
+
42
+ # Since Ruby is very dynamic, methods added to the ancestors of
43
+ # BlankSlate <em>after BlankSlate is defined</em> will show up in the
44
+ # list of available BlankSlate methods. We handle this by defining a
45
+ # hook in the Object and Kernel classes that will hide any defined
46
+ module Kernel #:nodoc:
47
+ class << self
48
+ alias_method :basic_object_method_added, :method_added
49
+
50
+ # Detect method additions to Kernel and remove them in the
51
+ # BlankSlate class.
52
+ def method_added(name)
53
+ basic_object_method_added(name)
54
+ return if self != Kernel
55
+ BasicObject.hide(name)
56
+ end
57
+ end
58
+ end
59
+
60
+ class Object #:nodoc:
61
+ class << self
62
+ alias_method :basic_object_method_added, :method_added
63
+
64
+ # Detect method additions to Object and remove them in the
65
+ # BlankSlate class.
66
+ def method_added(name)
67
+ basic_object_method_added(name)
68
+ return if self != Object
69
+ BasicObject.hide(name)
70
+ end
71
+ end
72
+ end
73
+
74
+ end
@@ -1 +1,288 @@
1
- require 'hashery/superstruct'
1
+ unless defined?(BasicObject)
2
+ require 'blankslate'
3
+ BasicObject = BlankSlate
4
+ end
5
+
6
+ # = BasicStruct
7
+ #
8
+ # BasicStruct is very similar to Ruby's own OpenStruct, but it offers some
9
+ # advantages. With OpenStruct, slots with the same name as predefined
10
+ # Object methods cannot be used. With BasicStruct, almost any slot can be
11
+ # defined. BasicStruct is a subclass of BasicObject to ensure all method
12
+ # slots, except those that are absolutely essential, are open for use.
13
+ #
14
+ #--
15
+ # If you wish to pass a BasicStruct to a routine that normal takes a Hash,
16
+ # but are uncertain it can handle the distictions properly you can convert
17
+ # easily to a Hash using #as_hash! and the result will automatically be
18
+ # converted back to an BasicStruct on return.
19
+ #
20
+ # o = BasicStruct.new(:a=>1,:b=>2)
21
+ # o.as_hash!{ |h| h.update(:a=>6) }
22
+ # o #=> #<BasicObject {:a=>6,:b=>2}>
23
+ #++
24
+ #
25
+ # Unlike a Hash, all BasicStruct's keys are symbols and all keys are converted
26
+ # to such using #to_sym on the fly.
27
+
28
+ class BasicStruct < BasicObject
29
+
30
+ #PUBLIC_METHODS = /(^__|^instance_|^object_|^\W|^as$|^send$|^class$|\?$)/
31
+ #protected(*public_instance_methods.select{ |m| m !~ PUBLIC_METHODS })
32
+
33
+ def self.[](hash=nil)
34
+ new(hash)
35
+ end
36
+
37
+ # Inititalizer for BasicObject is slightly different than that of Hash.
38
+ # It does not take a default parameter, but an initial priming Hash,
39
+ # like OpenStruct. The initializer can still take a default block
40
+ # however. To set the default value use <code>#default!(value)</code>.
41
+ #
42
+ # BasicObject.new(:a=>1).default!(0)
43
+ #
44
+ def initialize(hash=nil, &yld)
45
+ @table = ::Hash.new(&yld)
46
+ if hash
47
+ hash.each{ |k,v| store(k,v) }
48
+ end
49
+ end
50
+
51
+ #
52
+ def initialize_copy(orig)
53
+ orig.each{ |k,v| store(k,v) }
54
+ end
55
+
56
+ # Object inspection.
57
+ # TODO: Need to get __class__ and __id__ in hex form.
58
+ def inspect
59
+ #@table.inspect
60
+ hexid = __id__
61
+ klass = "BasicObject" # __class__
62
+ "#<#{klass}:#{hexid} #{@table.inspect}>"
63
+ end
64
+
65
+ # Convert to an associative array.
66
+ def to_a
67
+ @table.to_a
68
+ end
69
+
70
+ #
71
+ def to_h
72
+ @table.dup
73
+ end
74
+
75
+ #
76
+ def to_hash
77
+ @table.dup
78
+ end
79
+
80
+ #
81
+ def to_basicstruct
82
+ self
83
+ end
84
+
85
+ # Convert to an assignment procedure.
86
+ def to_proc(response=false)
87
+ hash = @table
88
+ if response
89
+ ::Proc.new do |o|
90
+ hash.each do |k,v|
91
+ o.__send__("#{k}=", v) rescue nil
92
+ end
93
+ end
94
+ else
95
+ ::Proc.new do |o|
96
+ hash.each{ |k,v| o.__send__("#{k}=", v) }
97
+ end
98
+ end
99
+ end
100
+
101
+ # NOT SURE ABOUT THIS
102
+ def as_hash
103
+ @table
104
+ end
105
+
106
+ # Is a given +key+ defined?
107
+ def key?(key)
108
+ @table.key?(key.to_sym)
109
+ end
110
+
111
+ #
112
+ def is_a?(klass)
113
+ return true if klass == ::Hash # TODO: Is this wise? How to fake a subclass?
114
+ return true if klass == ::BasicObject
115
+ false
116
+ end
117
+
118
+ # Iterate over each key-value pair.
119
+ def each(&yld)
120
+ @table.each(&yld)
121
+ end
122
+
123
+ # Set the default value.
124
+ def default!(default)
125
+ @table.default = default
126
+ end
127
+
128
+ # Check equality.
129
+ def ==( other )
130
+ case other
131
+ when ::BasicStruct
132
+ @table == other.as_hash
133
+ when ::Hash
134
+ @table == other
135
+ else
136
+ if other.respond_to?(:to_hash)
137
+ @table == other.to_hash
138
+ else
139
+ false
140
+ end
141
+ end
142
+ end
143
+
144
+ #
145
+ def eql?( other )
146
+ case other
147
+ when ::BasicStruct
148
+ @table.eql?(other.as_hash)
149
+ else
150
+ false
151
+ end
152
+ end
153
+
154
+ #
155
+ def <<(x)
156
+ case x
157
+ when ::Hash
158
+ @table.update(x)
159
+ when ::Array
160
+ x.each_slice(2) do |(k,v)|
161
+ @table[k] = v
162
+ end
163
+ end
164
+ end
165
+
166
+ #
167
+ def []=(key, value)
168
+ @table[key.to_sym] = value
169
+ end
170
+
171
+ #
172
+ def [](key)
173
+ @table[key.to_sym]
174
+ end
175
+
176
+ #
177
+ def merge!(other)
178
+ BasicObject.new(@table.merge!(other))
179
+ end
180
+
181
+ #
182
+ def update!(other)
183
+ @table.update(other)
184
+ self
185
+ end
186
+
187
+ #
188
+ def respond_to?(key)
189
+ key?(key)
190
+ end
191
+
192
+ # NOTE: These were protected, why?
193
+
194
+ #
195
+ def store(k, v)
196
+ @table.store(k.to_sym, v)
197
+ end
198
+
199
+ #
200
+ def fetch(k, *d, &b)
201
+ @table.fetch(k.to_sym, *d, &b)
202
+ end
203
+
204
+ protected
205
+
206
+ #def as_hash!
207
+ # Functor.new do |op,*a,&b|
208
+ # result = @table.__send__(op,*a,&b)
209
+ # case result
210
+ # when Hash
211
+ # BasicObject.new(result)
212
+ # else
213
+ # result
214
+ # end
215
+ # end
216
+ #end
217
+
218
+ #def define_slot(key, value=nil)
219
+ # @table[key.to_sym] = value
220
+ #end
221
+
222
+ #def protect_slot( key )
223
+ # (class << self; self; end).class_eval {
224
+ # protected key rescue nil
225
+ # }
226
+ #end
227
+
228
+ def method_missing(sym, *args, &blk)
229
+ type = sym.to_s[-1,1]
230
+ key = sym.to_s.sub(/[=?!]$/,'').to_sym
231
+ case type
232
+ when '='
233
+ store(key, args[0])
234
+ when '!'
235
+ @table.__send__(key, *args, &blk)
236
+ # if key?(key)
237
+ # fetch(key)
238
+ # else
239
+ # store(key, BasicObject.new)
240
+ # end
241
+ when '?'
242
+ fetch(key)
243
+ else
244
+ fetch(key)
245
+ end
246
+ end
247
+
248
+ end
249
+
250
+ # Core Extensions
251
+
252
+ class Hash
253
+ # Convert a Hash into a BasicStruct.
254
+ def to_basicstruct
255
+ BasicStruct[self]
256
+ end
257
+ end
258
+
259
+ =begin
260
+ class NilClass
261
+ # Nil converts to an empty BasicObject.
262
+ def to_basicstruct
263
+ BasicObject.new
264
+ end
265
+ end
266
+
267
+ class Proc
268
+ # Translates a Proc into an BasicObject. By droping an BasicObject into
269
+ # the Proc, the resulting assignments incured as the procedure is
270
+ # evaluated produce the BasicObject. This technique is simlar to that
271
+ # of MethodProbe.
272
+ #
273
+ # p = lambda { |x|
274
+ # x.word = "Hello"
275
+ # }
276
+ # o = p.to_basicstruct
277
+ # o.word #=> "Hello"
278
+ #
279
+ # NOTE The Proc must have an arity of one --no more and no less.
280
+ def to_basicstruct
281
+ raise ArgumentError, 'bad arity for converting Proc to basicstruct' if arity != 1
282
+ o = BasicObject.new
283
+ self.call( o )
284
+ o
285
+ end
286
+ end
287
+ =end
288
+
@@ -1,74 +1 @@
1
- # Facets' BasicObject is an implementation of Jim Weirich's BlankSlate.
2
- #
3
- # BlankSlate
4
- # Copyright 2004 by Jim Weirich (jim@weirichhouse.org).
5
- # All rights reserved.
6
- #
7
- # Since Ruby 1.9 has a BasicObject class this will of course be
8
- # deprecated as 1.9 goes mainstream.
9
-
10
- unless defined? BasicObject # in case it already exists!
11
-
12
- # BasicObject provides an abstract base class with no predefined
13
- # methods (except for <tt>\_\_send__</tt> and <tt>\_\_id__</tt>).
14
- # BlankSlate is useful as a base class when writing classes that
15
- # depend upon <tt>method_missing</tt> (e.g. dynamic proxies).
16
- class BasicObject
17
- class << self
18
- # Hide the method named +name+ in the BlankSlate class. Don't
19
- # hide +instance_eval+ or any method beginning with "__".
20
- #
21
- # According to 1.9.1 it should have only these methods:
22
- #
23
- # * #__send__
24
- # * #instance_eval
25
- # * #instance_exec
26
- # * #equal?
27
- # * #==
28
- # * #!
29
- # * #!=
30
- # * respond_to?
31
- #
32
- # Seems to me it should have #__id__ too.
33
- def hide(name)
34
- undef_method name if
35
- instance_methods.include?(name.to_s) and
36
- name !~ /^(__|respond_to\?|instance_eval$|instance_exec$|equal\?$|\=\=$)/
37
- end
38
- end
39
- instance_methods.each{ |m| hide(m) }
40
- end
41
-
42
- # Since Ruby is very dynamic, methods added to the ancestors of
43
- # BlankSlate <em>after BlankSlate is defined</em> will show up in the
44
- # list of available BlankSlate methods. We handle this by defining a
45
- # hook in the Object and Kernel classes that will hide any defined
46
- module Kernel #:nodoc:
47
- class << self
48
- alias_method :basic_object_method_added, :method_added
49
-
50
- # Detect method additions to Kernel and remove them in the
51
- # BlankSlate class.
52
- def method_added(name)
53
- basic_object_method_added(name)
54
- return if self != Kernel
55
- BasicObject.hide(name)
56
- end
57
- end
58
- end
59
-
60
- class Object #:nodoc:
61
- class << self
62
- alias_method :basic_object_method_added, :method_added
63
-
64
- # Detect method additions to Object and remove them in the
65
- # BlankSlate class.
66
- def method_added(name)
67
- basic_object_method_added(name)
68
- return if self != Object
69
- BasicObject.hide(name)
70
- end
71
- end
72
- end
73
-
74
- end
1
+ require 'hasery/basic_object'