hashery 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,21 @@
1
1
  = RELEASE HISTORY
2
2
 
3
+ == 1.3.0 // 2010-10-01
4
+
5
+ This release fixes a minor bug in CastingHash and adds a new
6
+ PropertyHash class.
7
+
8
+ Changes:
9
+
10
+ * 1 New Library
11
+
12
+ * Added PropertyHash
13
+
14
+ * 1 Bug Fix
15
+
16
+ * Fixed CastingHash#new where #to_proc is called against NilClass
17
+
18
+
3
19
  == 1.2.0 // 2010-06-04
4
20
 
5
21
  This release makes two signifficant changes to the Hashery.
data/LICENSE CHANGED
@@ -1,23 +1,206 @@
1
- The MIT License
1
+ .
2
2
 
3
- Copyright (c) 2005 Thomas Sawyer
3
+ Apache License
4
+ Version 2.0, January 2004
5
+ http://www.apache.org/licenses/
4
6
 
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
7
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
11
8
 
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
9
+ 1. Definitions.
14
10
 
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
11
+ "License" shall mean the terms and conditions for use, reproduction,
12
+ and distribution as defined by Sections 1 through 9 of this document.
22
13
 
14
+ "Licensor" shall mean the copyright owner or entity authorized by
15
+ the copyright owner that is granting the License.
16
+
17
+ "Legal Entity" shall mean the union of the acting entity and all
18
+ other entities that control, are controlled by, or are under common
19
+ control with that entity. For the purposes of this definition,
20
+ "control" means (i) the power, direct or indirect, to cause the
21
+ direction or management of such entity, whether by contract or
22
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
23
+ outstanding shares, or (iii) beneficial ownership of such entity.
24
+
25
+ "You" (or "Your") shall mean an individual or Legal Entity
26
+ exercising permissions granted by this License.
27
+
28
+ "Source" form shall mean the preferred form for making modifications,
29
+ including but not limited to software source code, documentation
30
+ source, and configuration files.
31
+
32
+ "Object" form shall mean any form resulting from mechanical
33
+ transformation or translation of a Source form, including but
34
+ not limited to compiled object code, generated documentation,
35
+ and conversions to other media types.
36
+
37
+ "Work" shall mean the work of authorship, whether in Source or
38
+ Object form, made available under the License, as indicated by a
39
+ copyright notice that is included in or attached to the work
40
+ (an example is provided in the Appendix below).
41
+
42
+ "Derivative Works" shall mean any work, whether in Source or Object
43
+ form, that is based on (or derived from) the Work and for which the
44
+ editorial revisions, annotations, elaborations, or other modifications
45
+ represent, as a whole, an original work of authorship. For the purposes
46
+ of this License, Derivative Works shall not include works that remain
47
+ separable from, or merely link (or bind by name) to the interfaces of,
48
+ the Work and Derivative Works thereof.
49
+
50
+ "Contribution" shall mean any work of authorship, including
51
+ the original version of the Work and any modifications or additions
52
+ to that Work or Derivative Works thereof, that is intentionally
53
+ submitted to Licensor for inclusion in the Work by the copyright owner
54
+ or by an individual or Legal Entity authorized to submit on behalf of
55
+ the copyright owner. For the purposes of this definition, "submitted"
56
+ means any form of electronic, verbal, or written communication sent
57
+ to the Licensor or its representatives, including but not limited to
58
+ communication on electronic mailing lists, source code control systems,
59
+ and issue tracking systems that are managed by, or on behalf of, the
60
+ Licensor for the purpose of discussing and improving the Work, but
61
+ excluding communication that is conspicuously marked or otherwise
62
+ designated in writing by the copyright owner as "Not a Contribution."
63
+
64
+ "Contributor" shall mean Licensor and any individual or Legal Entity
65
+ on behalf of whom a Contribution has been received by Licensor and
66
+ subsequently incorporated within the Work.
67
+
68
+ 2. Grant of Copyright License. Subject to the terms and conditions of
69
+ this License, each Contributor hereby grants to You a perpetual,
70
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
71
+ copyright license to reproduce, prepare Derivative Works of,
72
+ publicly display, publicly perform, sublicense, and distribute the
73
+ Work and such Derivative Works in Source or Object form.
74
+
75
+ 3. Grant of Patent License. Subject to the terms and conditions of
76
+ this License, each Contributor hereby grants to You a perpetual,
77
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
78
+ (except as stated in this section) patent license to make, have made,
79
+ use, offer to sell, sell, import, and otherwise transfer the Work,
80
+ where such license applies only to those patent claims licensable
81
+ by such Contributor that are necessarily infringed by their
82
+ Contribution(s) alone or by combination of their Contribution(s)
83
+ with the Work to which such Contribution(s) was submitted. If You
84
+ institute patent litigation against any entity (including a
85
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
86
+ or a Contribution incorporated within the Work constitutes direct
87
+ or contributory patent infringement, then any patent licenses
88
+ granted to You under this License for that Work shall terminate
89
+ as of the date such litigation is filed.
90
+
91
+ 4. Redistribution. You may reproduce and distribute copies of the
92
+ Work or Derivative Works thereof in any medium, with or without
93
+ modifications, and in Source or Object form, provided that You
94
+ meet the following conditions:
95
+
96
+ (a) You must give any other recipients of the Work or
97
+ Derivative Works a copy of this License; and
98
+
99
+ (b) You must cause any modified files to carry prominent notices
100
+ stating that You changed the files; and
101
+
102
+ (c) You must retain, in the Source form of any Derivative Works
103
+ that You distribute, all copyright, patent, trademark, and
104
+ attribution notices from the Source form of the Work,
105
+ excluding those notices that do not pertain to any part of
106
+ the Derivative Works; and
107
+
108
+ (d) If the Work includes a "NOTICE" text file as part of its
109
+ distribution, then any Derivative Works that You distribute must
110
+ include a readable copy of the attribution notices contained
111
+ within such NOTICE file, excluding those notices that do not
112
+ pertain to any part of the Derivative Works, in at least one
113
+ of the following places: within a NOTICE text file distributed
114
+ as part of the Derivative Works; within the Source form or
115
+ documentation, if provided along with the Derivative Works; or,
116
+ within a display generated by the Derivative Works, if and
117
+ wherever such third-party notices normally appear. The contents
118
+ of the NOTICE file are for informational purposes only and
119
+ do not modify the License. You may add Your own attribution
120
+ notices within Derivative Works that You distribute, alongside
121
+ or as an addendum to the NOTICE text from the Work, provided
122
+ that such additional attribution notices cannot be construed
123
+ as modifying the License.
124
+
125
+ You may add Your own copyright statement to Your modifications and
126
+ may provide additional or different license terms and conditions
127
+ for use, reproduction, or distribution of Your modifications, or
128
+ for any such Derivative Works as a whole, provided Your use,
129
+ reproduction, and distribution of the Work otherwise complies with
130
+ the conditions stated in this License.
131
+
132
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
133
+ any Contribution intentionally submitted for inclusion in the Work
134
+ by You to the Licensor shall be under the terms and conditions of
135
+ this License, without any additional terms or conditions.
136
+ Notwithstanding the above, nothing herein shall supersede or modify
137
+ the terms of any separate license agreement you may have executed
138
+ with Licensor regarding such Contributions.
139
+
140
+ 6. Trademarks. This License does not grant permission to use the trade
141
+ names, trademarks, service marks, or product names of the Licensor,
142
+ except as required for reasonable and customary use in describing the
143
+ origin of the Work and reproducing the content of the NOTICE file.
144
+
145
+ 7. Disclaimer of Warranty. Unless required by applicable law or
146
+ agreed to in writing, Licensor provides the Work (and each
147
+ Contributor provides its Contributions) on an "AS IS" BASIS,
148
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
149
+ implied, including, without limitation, any warranties or conditions
150
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
151
+ PARTICULAR PURPOSE. You are solely responsible for determining the
152
+ appropriateness of using or redistributing the Work and assume any
153
+ risks associated with Your exercise of permissions under this License.
154
+
155
+ 8. Limitation of Liability. In no event and under no legal theory,
156
+ whether in tort (including negligence), contract, or otherwise,
157
+ unless required by applicable law (such as deliberate and grossly
158
+ negligent acts) or agreed to in writing, shall any Contributor be
159
+ liable to You for damages, including any direct, indirect, special,
160
+ incidental, or consequential damages of any character arising as a
161
+ result of this License or out of the use or inability to use the
162
+ Work (including but not limited to damages for loss of goodwill,
163
+ work stoppage, computer failure or malfunction, or any and all
164
+ other commercial damages or losses), even if such Contributor
165
+ has been advised of the possibility of such damages.
166
+
167
+ 9. Accepting Warranty or Additional Liability. While redistributing
168
+ the Work or Derivative Works thereof, You may choose to offer,
169
+ and charge a fee for, acceptance of support, warranty, indemnity,
170
+ or other liability obligations and/or rights consistent with this
171
+ License. However, in accepting such obligations, You may act only
172
+ on Your own behalf and on Your sole responsibility, not on behalf
173
+ of any other Contributor, and only if You agree to indemnify,
174
+ defend, and hold each Contributor harmless for any liability
175
+ incurred by, or claims asserted against, such Contributor by reason
176
+ of your accepting any such warranty or additional liability.
177
+
178
+ END OF TERMS AND CONDITIONS
179
+
180
+ APPENDIX: How to apply the Apache License to your work.
181
+
182
+ To apply the Apache License to your work, attach the following
183
+ boilerplate notice, with the fields enclosed by brackets "[]"
184
+ replaced with your own identifying information. (Don't include
185
+ the brackets!) The text should be enclosed in the appropriate
186
+ comment syntax for the file format. We also recommend that a
187
+ file or class name and description of purpose be included on the
188
+ same "printed page" as the copyright notice for easier
189
+ identification within third-party archives.
190
+
191
+ Copyright [yyyy] [name of copyright owner]
192
+
193
+ Licensed under the Apache License, Version 2.0 (the "License");
194
+ you may not use this file except in compliance with the License.
195
+ You may obtain a copy of the License at
196
+
197
+ http://www.apache.org/licenses/LICENSE-2.0
198
+
199
+ Unless required by applicable law or agreed to in writing, software
200
+ distributed under the License is distributed on an "AS IS" BASIS,
201
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
202
+ See the License for the specific language governing permissions and
203
+ limitations under the License.
204
+
205
+ .
23
206
 
data/PROFILE ADDED
@@ -0,0 +1,35 @@
1
+ ---
2
+ title: Hashery
3
+ suite: rubyworks
4
+ summary: Facets bread collection of Hash-like classes.
5
+ license: MIT
6
+ contact: Trans <transfire@gmail.com>
7
+ created: 2010-04-21
8
+
9
+ authors:
10
+ - Thomas Sawyer
11
+ - Kirk Haines
12
+ - Robert Klemme
13
+ - Jan Molic
14
+ - George Moschovitis
15
+ - Jeena Paradies
16
+ - Erik Veenstra
17
+
18
+ description:
19
+ The Hashery is a collection of Hash-like classes, spun-off
20
+ from the original Ruby Facets library. Included are the widely
21
+ used OrderedHash, the related but more featured Dictionary
22
+ class, a number of open classes, similiar to the standard
23
+ OpenStruct and a few variations on the standard Hash.
24
+
25
+ resources:
26
+ home : http://rubyworks.github.com/hashery
27
+ code : http://github.com/rubyworks/hashery
28
+ mail : http://groups.google.com/group/rubyworks-mailinglist
29
+ api : http://rubyworks.github.com/hashery/docs/api
30
+ host : http://rubygems.org/gems/hashery
31
+ wiki : http://wiki.github.com/rubyworks/hashery
32
+ repo : git://github.com/rubyworks/hashery.git
33
+
34
+ copyright:
35
+ Copyright (c) 2010 Thomas Sawyer
@@ -25,7 +25,7 @@ Please see the HISTORY file.
25
25
 
26
26
  == HOW TO USE
27
27
 
28
- For usage information, see the individual library files include
28
+ For usage information, see the individual library files included
29
29
  in this collection.
30
30
 
31
31
 
@@ -39,18 +39,9 @@ Tarball packages are available for manual site installations
39
39
  via {Ruby Setup}[http://proutils.github.com/setup].
40
40
 
41
41
 
42
- == LICENSE
43
-
44
- Copyright (c) 2005, 2010 Thomas Sawyer
45
-
46
- This library is distributed under the terms of the MIT license.
42
+ == AUTHORS
47
43
 
48
- See LICENSE file for details.
49
-
50
- Some libraries included in the Hashery have special copyrights
51
- attributing specific authors. Please see each file for details.
52
-
53
- Contributing authors include:
44
+ Developers whose code has contributed the project include:
54
45
 
55
46
  * Kirk Haines
56
47
  * Joshua Hull
@@ -60,3 +51,28 @@ Contributing authors include:
60
51
  * Jeena Paradies
61
52
  * Erik Veenstra
62
53
 
54
+
55
+ == LICENSE
56
+
57
+ (Apache 2.0 License)
58
+
59
+ Copyright (c) 2010 Thomas Sawyer
60
+
61
+ Licensed under the Apache License, Version 2.0 (the "License");
62
+ you may not use this program except in compliance with the License.
63
+ You may obtain a copy of the License at
64
+
65
+ http://www.apache.org/licenses/LICENSE-2.0
66
+
67
+ Unless required by applicable law or agreed to in writing, software
68
+ distributed under the License is distributed on an "AS IS" BASIS,
69
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
70
+ See the License for the specific language governing permissions and
71
+ limitations under the License.
72
+
73
+ See LICENSE file for further details.
74
+
75
+ Some libraries included in the Hashery have special copyrights
76
+ attributing specific authors. Please see each library script for
77
+ specifics.
78
+
data/VERSION ADDED
@@ -0,0 +1,3 @@
1
+ name : hashery
2
+ version : 1.3.0
3
+ date : 2010-10-10
@@ -0,0 +1 @@
1
+ require 'hashery/castinghash'
@@ -20,8 +20,8 @@ class CastingHash < Hash
20
20
 
21
21
  #
22
22
  def initialize(hash={}, value_cast=nil, &key_cast)
23
- @key_proc = key_cast || KEY_PROC
24
- @value_proc = value_cast.to_proc || VAL_PROC
23
+ @key_proc = (key_cast || KEY_PROC)
24
+ @value_proc = (value_cast || VAL_PROC).to_proc
25
25
  hash.each{ |k,v| self[k] = v }
26
26
  end
27
27
 
@@ -0,0 +1 @@
1
+ require 'hashery/fuzzyhash'
@@ -0,0 +1,154 @@
1
+ require 'set'
2
+
3
+ # = Fuzzy Hash
4
+ #
5
+ # A weird hash with special semantics for regex keys.
6
+ #
7
+ # This is useful when you want to have a lookup table that can either contain strings or regexes.
8
+ # For instance, you might want a catch all for certain regexes that perform a certain logic.
9
+ #
10
+ # >> hash = FuzzyHash.new
11
+ # >> hash[/^\d+$/] = 'number'
12
+ # >> hash[/.*/] = 'something'
13
+ # >> hash['chunky'] = 'bacon'
14
+ # >> hash['foo'] = 'vader'
15
+ #
16
+ # >> hash['foo']
17
+ # << 'vader'
18
+ # >> hash['food']
19
+ # << 'something'
20
+ # >> hash['123']
21
+ # << 'number'
22
+ #
23
+ # Copyright (c) 2009 Joshua Hull
24
+
25
+ class FuzzyHash
26
+
27
+ def initialize(init_hash = nil)
28
+ @fuzzies = []
29
+ @hash_reverse = {}
30
+ @fuzzies_reverse = {}
31
+ @fuzzy_hash = {}
32
+ @hash = {}
33
+ init_hash.each{ |key,value| self[key] = value } if init_hash
34
+ end
35
+
36
+ def clear
37
+ hash.clear
38
+ fuzzies.clear
39
+ hash_reverse.clear
40
+ fuzzies_reverse.clear
41
+ end
42
+
43
+ def size
44
+ hash.size + fuzzies.size
45
+ end
46
+ alias_method :count, :size
47
+
48
+
49
+ def ==(o)
50
+ o.is_a?(FuzzyHash)
51
+ o.send(:hash) == hash &&
52
+ o.send(:fuzzies) == fuzzies
53
+ end
54
+
55
+ def empty?
56
+ hash.empty? && fuzzies.empty?
57
+ end
58
+
59
+ def keys
60
+ hash.keys + fuzzy_hash.keys
61
+ end
62
+
63
+ def values
64
+ hash.values + fuzzies.collect{|r| r.last}
65
+ end
66
+
67
+ def each
68
+ hash.each{|k,v| yield k,v }
69
+ fuzzies.each{|v| yield v.first, v.last }
70
+ end
71
+
72
+ def delete_value(value)
73
+ hash.delete(hash_reverse[value]) || ((rr = fuzzies_reverse[value]) && fuzzies.delete_at(rr[0]))
74
+ end
75
+
76
+ def []=(key, value)
77
+ if Regexp === key
78
+ fuzzies.delete_if{|f| f.first.inspect.hash == key.inspect.hash}
79
+ fuzzies_reverse.delete_if{|k, v| v[1].inspect.hash == key.inspect.hash}
80
+ hash_reverse.delete_if{|k,v| v.inspect.hash == key.inspect.hash}
81
+
82
+ fuzzy_hash[key] = value
83
+ fuzzies << [key, value]
84
+ reset_fuzz_test!
85
+ fuzzies_reverse[value] = [fuzzies.size - 1, key, value]
86
+ else
87
+ hash[key] = value
88
+ hash_reverse.delete_if{|k,v| v.hash == key.hash}
89
+ hash_reverse[value] = key
90
+ end
91
+ value
92
+ end
93
+
94
+ def replace(src, dest)
95
+ if hash_reverse.key?(src)
96
+ key = hash_reverse[src]
97
+ hash[key] = dest
98
+ hash_reverse.delete(src)
99
+ hash_reverse[dest] = key
100
+ elsif fuzzies_reverse.key?(src)
101
+ key = fuzzies_reverse[src]
102
+ fuzzies[rkey[0]] = [rkey[1], dest]
103
+ fuzzies_reverse.delete(src)
104
+ fuzzies_reverse[dest] = [rkey[0], rkey[1], dest]
105
+ end
106
+ end
107
+
108
+ def [](key)
109
+ (hash.key?(key) && hash[key]) ||
110
+ ((lookup = fuzzy_lookup(key)) && lookup && lookup.first) ||
111
+ fuzzy_hash[key]
112
+ end
113
+
114
+ def match_with_result(key)
115
+ if hash.key?(key)
116
+ [hash[key], key]
117
+ else
118
+ fuzzy_lookup(key)
119
+ end
120
+ end
121
+
122
+ private
123
+ attr_reader :fuzzies, :hash_reverse, :fuzzies_reverse, :hash, :fuzzy_hash
124
+ attr_writer :fuzz_test
125
+
126
+ def reset_fuzz_test!
127
+ self.fuzz_test = nil
128
+ end
129
+
130
+ def fuzz_test
131
+ unless @fuzz_test
132
+ @fuzz_test = Object.new
133
+ @fuzz_test.instance_variable_set(:'@fuzzies', fuzzies)
134
+ method = "
135
+ def match(str)
136
+ case str\n
137
+ "
138
+ fuzzies.each_with_index do |reg, index|
139
+ method << "when #{reg.first.inspect}; [@fuzzies[#{index}][1], Regexp.last_match(0)];"
140
+ end
141
+ method << "end\nend\n"
142
+ @fuzz_test.instance_eval method
143
+ end
144
+ @fuzz_test
145
+ end
146
+
147
+ def fuzzy_lookup(key)
148
+ if !fuzzies.empty? && (value = fuzz_test.match(key))
149
+ value
150
+ end
151
+ end
152
+
153
+ end
154
+
@@ -0,0 +1 @@
1
+ require 'hashery/linkedlist'
@@ -0,0 +1 @@
1
+ require 'hashery/lruhash'
@@ -0,0 +1 @@
1
+ require 'hashery/opencascade'
@@ -0,0 +1 @@
1
+ require 'hashery/openhash'
@@ -0,0 +1 @@
1
+ require 'hashery/open_object'
@@ -3,7 +3,7 @@ require 'hashery/openhash'
3
3
 
4
4
  # = OpenCascade
5
5
  #
6
- # OpenCascade is subclass of OpenObject. It differs in a few
6
+ # OpenCascade is subclass of OpenHash. It differs in a few
7
7
  # significant ways.
8
8
  #
9
9
  # The main reason this class is labeled "cascade", every internal
@@ -0,0 +1 @@
1
+ require 'hashery/orderedhash'
@@ -0,0 +1 @@
1
+ require 'hashery/propertyhash'
@@ -0,0 +1,97 @@
1
+ # A PropertyHash is the same as a regular Hash except it strictly limits the
2
+ # allowed keys.
3
+ #
4
+ # There are two ways to use it.
5
+ #
6
+ # 1) As an object in itself.
7
+ #
8
+ # h = PropertyHash.new(:a=>1, :b=>2)
9
+ # h[:a] #=> 1
10
+ # h[:a] = 3
11
+ # h[:a] #=> 3
12
+ #
13
+ # But if we try to set key that was not fixed, then we will get an error.
14
+ #
15
+ # h[:x] = 5 #=> ArgumentError
16
+ #
17
+ # 2) As a superclass.
18
+ #
19
+ # class MyPropertyHash < PropertyHash
20
+ # property :a, :default => 1
21
+ # property :b, :default => 2
22
+ # end
23
+ #
24
+ # h = MyPropertyHash.new
25
+ # h[:a] #=> 1
26
+ # h[:a] = 3
27
+ # h[:a] #=> 3
28
+ #
29
+ # Again, if we try to set key that was not fixed, then we will get an error.
30
+ #
31
+ # h[:x] = 5 #=> ArgumentError
32
+ #
33
+ class PropertyHash < Hash
34
+
35
+ #
36
+ def self.properties
37
+ @properties ||= (
38
+ parent = ancestors[1]
39
+ if parent.respond_to?(:properties)
40
+ parent.properties
41
+ else
42
+ {}
43
+ end
44
+ )
45
+ end
46
+
47
+ #
48
+ def self.property(key, opts={})
49
+ properties[key] = opts[:default]
50
+ end
51
+
52
+ #
53
+ def initialize(properties={})
54
+ super()
55
+ fixed = self.class.properties.merge(properties)
56
+ replace(fixed)
57
+ end
58
+
59
+ #
60
+ def []=(k,v)
61
+ assert_key!(k)
62
+ super(k,v)
63
+ end
64
+
65
+ #
66
+ def update(h)
67
+ h.keys.each{ |k| assert_key!(k) }
68
+ super(h)
69
+ end
70
+
71
+ #
72
+ def merge!(h)
73
+ h.keys.each{ |k| assert_key!(k) }
74
+ super(h)
75
+ end
76
+
77
+ #
78
+ def <<(a)
79
+ k,v = *a
80
+ self[k] = v
81
+ end
82
+
83
+ # Add a new acceptable key.
84
+ # TODO: Should this be supported?
85
+ def accept_key!(k,v=nil)
86
+ self[k] = v
87
+ end
88
+
89
+ private
90
+
91
+ def assert_key!(key)
92
+ unless key?(key)
93
+ raise ArgumentError, "The key '#{key}' is not defined for this FixedHash."
94
+ end
95
+ end
96
+
97
+ end
@@ -0,0 +1 @@
1
+ require 'hashery/queryhash'
@@ -0,0 +1 @@
1
+ require 'hashery/sparsearray'
@@ -0,0 +1 @@
1
+ require 'hashery/statichash'
@@ -0,0 +1,316 @@
1
+ require 'hashery/sparsearray'
2
+ require 'ae/legacy'
3
+
4
+ # This is a mostly complete testcase for SparseArray.
5
+ # SparseArray is tested by comparison to standard Array.
6
+
7
+ Case SparseArray do
8
+
9
+ def aha(a)
10
+ return a, SparseArray[*a]
11
+ end
12
+
13
+ Unit :to_ary do
14
+ a, ha = aha [1,3,'a',8,nil,[1]]
15
+ assert_equal(ha, ha.to_ary) # these need to be opposite
16
+ end
17
+
18
+ Unit :to_a do
19
+ a, ha = aha [1,3,'a',8,nil,[1]]
20
+ assert_equal(a, ha.to_a) #
21
+ assert_equal(a.to_s, ha.to_s)
22
+ end
23
+
24
+ Unit :to_s do
25
+ a, ha = aha [1,3,'a',8,nil,[1]]
26
+ assert_equal(a.to_s, ha.to_s)
27
+ end
28
+
29
+ Unit :|, :&, :+, :- do
30
+ a, ha = aha [1,3,5,8,9]
31
+ b, hb = aha [2,3,6,8,9]
32
+ assert_equal(a | b, (ha | hb).to_a)
33
+ assert_equal(a & b, (ha & hb).to_a)
34
+ assert_equal(a + b, (ha + hb).to_a)
35
+ assert_equal(a - b, (ha - hb).to_a)
36
+ end
37
+
38
+ Unit :* do
39
+ a, ha = aha [1,3]
40
+ assert_equal(a*3,(ha*3).to_a)
41
+ end
42
+
43
+ Unit :[]= do
44
+ a, ha = aha [1,2,3,4]
45
+ a[1..2] = [8,9]
46
+ ha[1..2] = [8,9]
47
+ assert_equal(a, ha.to_a)
48
+ end
49
+
50
+ Unit :assoc do
51
+ a, ha = aha [[1,2],[3,4],[3,6]]
52
+ assert_equal(a.assoc(3), ha.assoc(3).to_a)
53
+ end
54
+
55
+ Unit :at do
56
+ a, ha = aha [4,5,6,6]
57
+ assert_equal(a.at(0), ha.at(0))
58
+ assert_equal(a.at(2), ha.at(2))
59
+ assert_equal(a.at(4), ha.at(4))
60
+ assert_equal(a.at(9), ha.at(9))
61
+ assert_equal(a.at(-1), ha.at(-1))
62
+ assert_equal(a.at(-3), ha.at(-3))
63
+ assert_equal(a.at(-4), ha.at(-4))
64
+ assert_equal(a.at(-5), ha.at(-5))
65
+ end
66
+
67
+ Unit :collect do
68
+ a, ha = aha [4,5,6,6]
69
+ assert_equal(a.collect{|e|e}, ha.collect{|e|e}.to_a)
70
+ assert_equal(a.collect!{|e|e}, ha.collect!{|e|e}.to_a)
71
+ assert_equal(a,ha.to_a)
72
+ end
73
+
74
+ Unit :compact do
75
+ a, ha = aha [4,nil,5,nil,6]
76
+ assert_equal(a.compact, ha.compact.to_a)
77
+ end
78
+
79
+ Unit :concat do
80
+ a, ha = aha [1,3,5,8,9]
81
+ b, hb = aha [2,3,6,8,9]
82
+ assert_equal(a.concat(b),ha.concat(hb).to_a)
83
+ end
84
+
85
+ Unit :count do
86
+ ha = SparseArray[9,3,9,5,nil,nil,9,3]
87
+ assert_equal(2,ha.count)
88
+ assert_equal(2,ha.count(3))
89
+ assert_equal(3,ha.count{|e|e==9})
90
+ end
91
+
92
+ Unit :delete do
93
+ a, ha = aha [1,3,5,8,9,'a','b','c','c','d']
94
+ # test delete
95
+ assert_equal(a.delete(1),ha.delete(1))
96
+ assert_equal(a,ha.to_a)
97
+ assert_equal(a.delete('a'),ha.delete('a'))
98
+ assert_equal(a,ha.to_a)
99
+ # test delete_at
100
+ assert_equal(a.delete_at(0),ha.delete_at(0))
101
+ assert_equal(a,ha.to_a)
102
+ # test delete_if
103
+ assert_equal(a.delete_if{|v|v=='c'},ha.delete_if{|v|v=='c'}.to_a)
104
+ assert_equal(a,ha.to_a)
105
+ end
106
+
107
+ Unit :each do
108
+ a, ha = aha [4,'a',nil,'b']
109
+ # test each
110
+ ca, cha = '', ''
111
+ a.each{|e| ca += e.to_s}
112
+ ha.each{|e| cha += e.to_s}
113
+ assert_equal(ca,cha)
114
+ assert_equal(a,ha.to_a)
115
+ # test each_index
116
+ ca, cha = '', ''
117
+ a.each_index{|i| ca += i.to_s}
118
+ ha.each_index{|i| cha += i.to_s}
119
+ assert_equal(ca,cha)
120
+ assert_equal(a,ha.to_a)
121
+ end
122
+
123
+ Unit :eql? do
124
+ a, ha = aha [4,'a',nil,'b']
125
+ b, hb = aha [4,'a',nil,'b']
126
+ assert_equal(a,b)
127
+ assert_equal(ha,hb)
128
+ assert_equal(a.eql?(b),ha.eql?(hb))
129
+ assert_equal(b.eql?(a),hb.eql?(ha))
130
+ assert(ha.eql?(hb))
131
+ assert(hb.eql?(ha))
132
+ end
133
+
134
+ Unit :empty? do
135
+ a, ha = aha []
136
+ assert_equal(a.empty?,ha.empty?)
137
+ a, ha = aha [1,2,3]
138
+ assert_equal(a.empty?,ha.empty?)
139
+ end
140
+
141
+ Unit :fill do
142
+ a, ha = aha ['a','b','c','d']
143
+ assert_equal(a.fill('x'),ha.fill('x').to_a)
144
+ assert_equal(a,ha.to_a)
145
+ assert_equal(a.fill('y',2,2),ha.fill('y',2,2).to_a)
146
+ assert_equal(a,ha.to_a)
147
+ assert_equal(a.fill('z',0..1),ha.fill('z',0..1).to_a)
148
+ assert_equal(a,ha.to_a)
149
+ end
150
+
151
+ Unit :first do
152
+ a, ha = aha [2,3,4]
153
+ assert_equal(a.first,ha.first)
154
+ end
155
+
156
+ Unit :flatten do
157
+ a, ha = aha [2,[3],'a',[[1,2],4],nil,5]
158
+ assert_equal(a.flatten,ha.flatten.to_a)
159
+ a, ha = aha [2,[3],'a',[[1,2],4],nil,5]
160
+ assert_equal(a.flatten!,ha.flatten!.to_a)
161
+ assert_equal(a,ha.to_a)
162
+ a, ha = aha [2,3,'a',nil,5]
163
+ assert_equal(a.flatten!,ha.flatten!)
164
+ end
165
+
166
+ Unit :include? do
167
+ a, ha = aha ['a','b','c','d']
168
+ assert_equal(a.include?('b'),ha.include?('b'))
169
+ assert_equal(a.include?('x'),ha.include?('x'))
170
+ end
171
+
172
+ Unit :index do
173
+ a, ha = aha ['a','b','b','c','d']
174
+ assert_equal(a.index('b'),ha.index('b'))
175
+ assert_equal(a.index('x'),ha.index('x'))
176
+ end
177
+
178
+ Unit :join do
179
+ a, ha = aha [2,3,4]
180
+ assert_equal(a.join,ha.join)
181
+ assert_equal(a.join(','),ha.join(','))
182
+ end
183
+
184
+ Unit :last do
185
+ a, ha = aha [2,3,4]
186
+ assert_equal(a.last,ha.last)
187
+ end
188
+
189
+ Unit :length do
190
+ a, ha = aha [2,3,4]
191
+ assert_equal(a.length,ha.length)
192
+ end
193
+
194
+ Unit :map! do
195
+ a, ha = aha [4,5,6,6]
196
+ assert_equal(a.map!{|e|e}, ha.map!{|e|e}.to_a)
197
+ assert_equal(a,ha.to_a)
198
+ end
199
+
200
+ Unit :nitems do
201
+ a, ha = aha [4,5,nil,6,nil]
202
+ assert_equal(a.nitems, ha.nitems)
203
+ end
204
+
205
+ Unit :pop do
206
+ a, ha = aha [4,5,nil,6,nil]
207
+ assert_equal(a.pop, ha.pop)
208
+ assert_equal(a, ha.to_a)
209
+ assert_equal(a.pop, ha.pop)
210
+ assert_equal(a, ha.to_a)
211
+ end
212
+
213
+ Unit :push do
214
+ a, ha = aha [4,5,nil,6,nil]
215
+ args = [1,2,3]
216
+ assert_equal(a.push(*args), ha.push(*args).to_a)
217
+ assert_equal(a, ha.to_a)
218
+ end
219
+
220
+ Unit :rassoc do
221
+ a, ha = aha [[1,2],[1,3],[1,3]]
222
+ assert_equal(a.rassoc(3), ha.rassoc(3).to_a)
223
+ end
224
+
225
+ Unit :reject! do
226
+ a, ha = aha ['a','b','c','c','d']
227
+ assert_equal(a.reject!{|v|v=='c'},ha.reject!{|v|v=='c'}.to_a)
228
+ assert_equal(a,ha.to_a)
229
+ assert_equal(a.reject!{|v|v=='x'},ha.reject!{|v|v=='x'})
230
+ assert_equal(a,ha.to_a)
231
+ end
232
+
233
+ Unit :reverse do
234
+ a, ha = aha ['a','b','c','c','d']
235
+ assert_equal(a.reverse,ha.reverse.to_a)
236
+ assert_equal(a.reverse!,ha.reverse!.to_a)
237
+ assert_equal(a,ha.to_a)
238
+ a, ha = aha [1,2,3,'a','b','c']
239
+ assert_equal(a.reverse!,ha.reverse!.to_a)
240
+ assert_equal(a,ha.to_a)
241
+ end
242
+
243
+ Unit :reverse_each do
244
+ a, ha = aha [4,'a',nil,'b']
245
+ # test each
246
+ ca, cha = '', ''
247
+ a.reverse_each{|e| ca += e.to_s}
248
+ ha.reverse_each{|e| cha += e.to_s}
249
+ assert_equal(ca,cha)
250
+ assert_equal(a,ha.to_a)
251
+ end
252
+
253
+ Unit :rindex do
254
+ a, ha = aha ['a','b','c','c','d']
255
+ assert_equal(a.rindex('c'),ha.rindex('c'))
256
+ assert_equal(a.rindex('x'),ha.rindex('x'))
257
+ end
258
+
259
+ Unit :shift do
260
+ a, ha = aha ['a','b','c','c','d']
261
+ assert_equal(a.shift,ha.shift)
262
+ assert_equal(a,ha.to_a)
263
+ end
264
+
265
+ Unit :slice do
266
+ a, ha = aha [1,2,3,4]
267
+ # test []
268
+ assert_equal(a[1], ha[1])
269
+ assert_equal(a[1..2], ha[1..2].to_a)
270
+ assert_equal(a[1...2], ha[1...2].to_a)
271
+ assert_equal(a[1..7], ha[1..7].to_a)
272
+ assert_equal(a[1,2], ha[1,2].to_a)
273
+ # test slice
274
+ assert_equal(a.slice(1), ha.slice(1))
275
+ assert_equal(a.slice(1..2), ha.slice(1..2).to_a)
276
+ assert_equal(a.slice(1...2), ha.slice(1...2).to_a)
277
+ assert_equal(a.slice(1...2), ha.slice(1...2).to_a)
278
+ assert_equal(a.slice(1,2), ha.slice(1,2).to_a)
279
+ # test slice!
280
+ assert_equal(a.slice!(1..2), ha.slice!(1..2).to_a)
281
+ assert_equal(a, ha.to_a)
282
+ end
283
+
284
+ Unit :sort do
285
+ a, ha = aha [1,2,3,4]
286
+ # test sort
287
+ assert_equal(a.sort, ha.sort.to_a)
288
+ #assert_equal(a.sort{|x,y| y<=>x}, ha.sort{|x,y| y<=>x}.to_a)
289
+ # test sort!
290
+ assert_equal(a.sort!, ha.sort!.to_a)
291
+ assert_equal(a, ha.to_a)
292
+ end
293
+
294
+ Unit :uniq do
295
+ a, ha = aha [1,1,2,3,3,4,5,6,6]
296
+ assert_equal(a.uniq, ha.uniq.to_a)
297
+ end
298
+
299
+ Unit :uniq! do
300
+ a, ha = aha [1,1,2,3,3,4,5,6,6]
301
+ a.uniq!; ha.uniq!
302
+ assert_equal(a, ha.to_a)
303
+ end
304
+
305
+ Unit :values_at do
306
+ a, ha = aha ['a','b','c','d']
307
+ assert_equal(a.values_at(1,3),ha.values_at(1,3).to_a)
308
+ end
309
+
310
+ Unit :unshift do
311
+ a, ha = aha ['a','b','c','c','d']
312
+ assert_equal(a.unshift('x'),ha.unshift('x').to_a)
313
+ assert_equal(a,ha.to_a)
314
+ end
315
+ end
316
+
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 1
7
- - 2
7
+ - 3
8
8
  - 0
9
- version: 1.2.0
9
+ version: 1.3.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Thomas Sawyer
@@ -20,7 +20,7 @@ autorequire:
20
20
  bindir: bin
21
21
  cert_chain: []
22
22
 
23
- date: 2010-06-04 00:00:00 -04:00
23
+ date: 2010-10-10 00:00:00 -04:00
24
24
  default_executable:
25
25
  dependencies: []
26
26
 
@@ -34,20 +34,34 @@ extra_rdoc_files:
34
34
  - README.rdoc
35
35
  files:
36
36
  - lib/hashery/association.rb
37
+ - lib/hashery/casting_hash.rb
37
38
  - lib/hashery/castinghash.rb
38
39
  - lib/hashery/dictionary.rb
40
+ - lib/hashery/fuzzy_hash.rb
41
+ - lib/hashery/fuzzyhash.rb
39
42
  - lib/hashery/ini.rb
43
+ - lib/hashery/linked_list.rb
40
44
  - lib/hashery/linkedlist.rb
45
+ - lib/hashery/lru_hash.rb
41
46
  - lib/hashery/lruhash.rb
42
47
  - lib/hashery/memoizer.rb
48
+ - lib/hashery/open_cascade.rb
49
+ - lib/hashery/open_hash.rb
50
+ - lib/hashery/open_object.rb
43
51
  - lib/hashery/opencascade.rb
44
52
  - lib/hashery/openhash.rb
45
53
  - lib/hashery/openobject.rb
54
+ - lib/hashery/ordered_hash.rb
46
55
  - lib/hashery/orderedhash.rb
47
56
  - lib/hashery/ostructable.rb
57
+ - lib/hashery/property_hash.rb
58
+ - lib/hashery/propertyhash.rb
59
+ - lib/hashery/query_hash.rb
48
60
  - lib/hashery/queryhash.rb
61
+ - lib/hashery/sparse_array.rb
49
62
  - lib/hashery/sparsearray.rb
50
63
  - lib/hashery/stash.rb
64
+ - lib/hashery/static_hash.rb
51
65
  - lib/hashery/statichash.rb
52
66
  - lib/hashery.rb
53
67
  - test/case_association.rb
@@ -55,15 +69,17 @@ files:
55
69
  - test/case_opencascade.rb
56
70
  - test/case_openhash.rb
57
71
  - test/case_openobject.rb
72
+ - test/case_sparsearray.rb
58
73
  - test/case_stash.rb
74
+ - HISTORY.rdoc
75
+ - PROFILE
59
76
  - LICENSE
60
77
  - README.rdoc
61
- - ROADMAP.rdoc
62
- - HISTORY
78
+ - VERSION
63
79
  has_rdoc: true
64
80
  homepage: http://rubyworks.github.com/hashery
65
- licenses: []
66
-
81
+ licenses:
82
+ - MIT
67
83
  post_install_message:
68
84
  rdoc_options:
69
85
  - --title
@@ -73,6 +89,7 @@ rdoc_options:
73
89
  require_paths:
74
90
  - lib
75
91
  required_ruby_version: !ruby/object:Gem::Requirement
92
+ none: false
76
93
  requirements:
77
94
  - - ">="
78
95
  - !ruby/object:Gem::Version
@@ -80,6 +97,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
80
97
  - 0
81
98
  version: "0"
82
99
  required_rubygems_version: !ruby/object:Gem::Requirement
100
+ none: false
83
101
  requirements:
84
102
  - - ">="
85
103
  - !ruby/object:Gem::Version
@@ -89,7 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
107
  requirements: []
90
108
 
91
109
  rubyforge_project: hashery
92
- rubygems_version: 1.3.6
110
+ rubygems_version: 1.3.7
93
111
  signing_key:
94
112
  specification_version: 3
95
113
  summary: Facets bread collection of Hash-like classes.
@@ -1,13 +0,0 @@
1
- = ROADMAP
2
-
3
- == 1.1.0
4
-
5
- * Improve test coverage.
6
- * Consider using Hashery:: namespace.
7
- * Should Stash have a more explict name?
8
-
9
- == 1.2.0
10
-
11
- * Add a defined property Hash. Needed?
12
- * Any other Hash-like classes to add?
13
-