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
@@ -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'