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,167 +1 @@
1
- # = OrderedHash
2
- #
3
- # A simple ordered hash implmentation, for users of
4
- # Ruby 1.8.7 or less.
5
- #
6
- # NOTE: As of Ruby 1.9+ this class is not needed, since
7
- # Ruby 1.9's standard Hash tracks inseration order.
8
- #
9
- # This implementation derives from the same class in
10
- # ActiveSupport library.
11
-
12
- class OrderedHash < ::Hash
13
- def to_yaml_type
14
- "!tag:yaml.org,2002:omap"
15
- end
16
-
17
- def to_yaml(opts = {})
18
- YAML.quick_emit(self, opts) do |out|
19
- out.seq(taguri, to_yaml_style) do |seq|
20
- each do |k, v|
21
- seq.add(k => v)
22
- end
23
- end
24
- end
25
- end
26
-
27
- # Hash is ordered in Ruby 1.9!
28
- if RUBY_VERSION < '1.9'
29
- def initialize(*args, &block)
30
- super
31
- @keys = []
32
- end
33
-
34
- def self.[](*args)
35
- ordered_hash = new
36
-
37
- if (args.length == 1 && args.first.is_a?(Array))
38
- args.first.each do |key_value_pair|
39
- next unless (key_value_pair.is_a?(Array))
40
- ordered_hash[key_value_pair[0]] = key_value_pair[1]
41
- end
42
-
43
- return ordered_hash
44
- end
45
-
46
- unless (args.size % 2 == 0)
47
- raise ArgumentError.new("odd number of arguments for Hash")
48
- end
49
-
50
- args.each_with_index do |val, ind|
51
- next if (ind % 2 != 0)
52
- ordered_hash[val] = args[ind + 1]
53
- end
54
-
55
- ordered_hash
56
- end
57
-
58
- def initialize_copy(other)
59
- super(other)
60
- @keys = other.keys
61
- end
62
-
63
- def []=(key, value)
64
- @keys << key unless key?(key)
65
- super(key, value)
66
- end
67
-
68
- def delete(key)
69
- if has_key? key
70
- index = @keys.index(key)
71
- @keys.delete_at(index)
72
- end
73
- super(key)
74
- end
75
-
76
- def delete_if
77
- super
78
- sync_keys!
79
- self
80
- end
81
-
82
- def reject!
83
- super
84
- sync_keys!
85
- self
86
- end
87
-
88
- def reject(&block)
89
- dup.reject!(&block)
90
- end
91
-
92
- def keys
93
- @keys.dup
94
- end
95
-
96
- def values
97
- @keys.collect{ |key| self[key] }
98
- end
99
-
100
- def to_hash
101
- self
102
- end
103
-
104
- def to_a
105
- @keys.map{ |key| [ key, self[key] ] }
106
- end
107
-
108
- def each_key
109
- @keys.each{ |key| yield(key) }
110
- end
111
-
112
- def each_value
113
- @keys.each{ |key| yield(self[key]) }
114
- end
115
-
116
- def each
117
- @keys.each{ |key| yield(key, self[key]) }
118
- end
119
-
120
- alias_method :each_pair, :each
121
-
122
- def clear
123
- super
124
- @keys.clear
125
- self
126
- end
127
-
128
- def shift
129
- k = @keys.first
130
- v = delete(k)
131
- [k, v]
132
- end
133
-
134
- def merge!(other_hash)
135
- other_hash.each{ |k,v| self[k] = v }
136
- self
137
- end
138
-
139
- def merge(other_hash)
140
- dup.merge!(other_hash)
141
- end
142
-
143
- # When replacing with another hash, the initial order of our
144
- # keys must come from the other hash, ordered or not.
145
- def replace(other)
146
- super
147
- @keys = other.keys
148
- self
149
- end
150
-
151
- def inspect
152
- "#<OrderedHash #{super}>"
153
- end
154
-
155
- private
156
- def sync_keys!
157
- @keys.delete_if{ |k| !key?(k) }
158
- end
159
- end
160
- end
161
-
162
- require 'yaml'
163
-
164
- YAML.add_builtin_type("omap") do |type, val|
165
- ActiveSupport::OrderedHash[val.map(&:to_a).map(&:first)]
166
- end
167
-
1
+ require 'hashery/ordered_hash'
@@ -1 +1,97 @@
1
- require 'hashery/propertyhash'
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
@@ -1,97 +1 @@
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
1
+ require 'hashery/property_hash'
@@ -1 +1,35 @@
1
- require 'hashery/queryhash'
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
19
+
20
+ def to_hash
21
+ dup
22
+ end
23
+
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)
32
+ end
33
+ end
34
+
35
+ end
@@ -1,35 +1 @@
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
19
-
20
- def to_hash
21
- dup
22
- end
23
-
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)
32
- end
33
- end
34
-
35
- end
1
+ require 'hashery/query_hash'
@@ -1,181 +1,10 @@
1
- # Stash is just like Hash, except that all keys are
2
- # converted to Strings.
3
- #
4
- # Note this doesn't yet handle default_proc.
1
+ require 'hashery/keyhash'
5
2
 
6
- class Stash < Hash
7
-
8
- #
9
- def self.[](*hash)
10
- s = new
11
- super(*hash).each{ |k,v| s[k] = v }
12
- s
13
- end
14
-
15
- #
16
- def [](key)
17
- super(convert_key(key))
18
- end
19
-
20
- #
21
- def []=(key,value)
22
- super(convert_key(key), value)
23
- end
24
-
25
- #
26
- def <<(other)
27
- case other
28
- when Hash
29
- super(other.rekey{ |key| convert_key(key) })
30
- when Array
31
- self[other[0]] = other[1]
32
- else
33
- raise ArgumentError
34
- end
35
- end
36
-
37
- #
38
- def fetch(key)
39
- super(convert_key(key))
40
- end
41
-
42
- #
43
- def store(key, value)
44
- super(convert_key(key), value)
45
- end
46
-
47
- #
48
- def key?(key)
49
- super(convert_key(key))
50
- end
51
-
52
- #
53
- def has_key?(key)
54
- super(convert_key(key))
55
- end
56
-
57
- #
58
- def include?(key)
59
- super(convert_key(key))
60
- end
61
-
62
- #
63
- def member?(key)
64
- super(convert_key(key))
65
- end
66
-
67
-
68
- # Synonym for Hash#rekey, but modifies the receiver in place (and returns it).
69
- #
70
- # foo = { :name=>'Gavin', :wife=>:Lisa }.to_stash
71
- # foo.rekey!{ |k| k.upcase } #=> { "NAME"=>"Gavin", "WIFE"=>:Lisa }
72
- # foo.inspect #=> { "NAME"=>"Gavin", "WIFE"=>:Lisa }
73
- #
74
- def rekey!(*args, &block)
75
- # for backward comptability (TODO: DEPRECATE?).
76
- block = args.pop.to_sym.to_proc if args.size == 1
77
- if args.empty?
78
- block = lambda{|k| k} unless block
79
- keys.each do |k|
80
- nk = block[k]
81
- self[nk.to_s]=delete(k) #if nk
82
- end
83
- else
84
- raise ArgumentError, "3 for 2" if block
85
- to, from = *args
86
- self[to] = delete(from) if has_key?(from)
87
- end
88
- self
89
- end
90
-
91
- #
92
- def rekey(*args, &block)
93
- dup.rekey!(*args, &block)
94
- end
95
-
96
- #
97
- def delete(key)
98
- super(convert_key(key))
99
- end
100
-
101
- #
102
- def update(other)
103
- super(other.rekey{ |key| convert_key(key) })
104
- end
105
-
106
- # Same as #update.
107
- def merge!(other)
108
- super(other.rekey{ |key| convert_key(key) })
109
- end
110
-
111
- #
112
- def merge(other)
113
- super(other.rekey{ |key| convert_key(key) })
114
- end
115
-
116
- #
117
- def replace(other)
118
- super(other.rekey{ |key| convert_key(key) })
119
- end
120
-
121
- #
122
- def values_at(*keys)
123
- super(*keys.map{ |key| convert_key(key) })
124
- end
125
-
126
- #
127
- def to_hash
128
- h = {}
129
- each{ |k,v| h[k] = v }
130
- h
131
- end
132
-
133
- alias_method :to_h, :to_hash
134
-
135
- private
136
-
137
- def convert_key(key)
138
- key.to_s
139
- end
140
-
141
- end
3
+ Stash = KeyHash
142
4
 
143
5
  class Hash
144
-
145
- # Convert a Hash to a Stash object.
6
+ # Convert Hash to Stash.
146
7
  def to_stash
147
8
  Stash[self]
148
9
  end
149
-
150
- # Synonym for Hash#rekey, but modifies the receiver in place (and returns it).
151
- #
152
- # foo = { :name=>'Gavin', :wife=>:Lisa }
153
- # foo.rekey!{ |k| k.to_s } #=> { "name"=>"Gavin", "wife"=>:Lisa }
154
- # foo.inspect #=> { "name"=>"Gavin", "wife"=>:Lisa }
155
- #
156
- # This method comes from Ruby Facets.
157
-
158
- def rekey!(*args, &block)
159
- # for backward comptability (TODO: DEPRECATE).
160
- block = args.pop.to_sym.to_proc if args.size == 1
161
- if args.empty?
162
- block = lambda{|k| k.to_sym} unless block
163
- keys.each do |k|
164
- nk = block[k]
165
- self[nk]=delete(k) if nk
166
- end
167
- else
168
- raise ArgumentError, "3 for 2" if block
169
- to, from = *args
170
- self[to] = self.delete(from) if self.has_key?(from)
171
- end
172
- self
173
- end
174
-
175
- # Non-inplace #rekey! method.
176
- def rekey(*args, &block)
177
- dup.rekey!(*args, &block)
178
- end
179
-
180
10
  end
181
-