map 1.2.0 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/map.rb +69 -65
  2. data/test/map_test.rb +15 -0
  3. metadata +4 -4
data/lib/map.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  class Map < Hash
2
- Version = '1.2.0' unless defined?(Version)
2
+ Version = '1.2.3' unless defined?(Version)
3
3
  Load = Kernel.method(:load) unless defined?(Load)
4
4
 
5
5
  class << Map
@@ -7,41 +7,14 @@ class Map < Hash
7
7
  Map::Version
8
8
  end
9
9
 
10
- # class constructor
11
- #
12
10
  def new(*args, &block)
13
- case args.size
14
- when 0
15
- super(&block)
16
-
17
- when 1
18
- case args.first
19
- when Hash
20
- new_from_hash(args.first)
21
- when Array
22
- new_from_array(args.first)
23
- else
24
- new_from_hash(args.first.to_hash)
25
- end
26
-
27
- else
28
- new_from_array(args)
11
+ allocate.instance_eval do
12
+ @keys = []
13
+ initialize(*args, &block)
14
+ self
29
15
  end
30
16
  end
31
17
 
32
- def new_from_hash(hash)
33
- map = new
34
- map.update(hash)
35
- map.default = hash.default
36
- map
37
- end
38
-
39
- def new_from_array(array)
40
- map = new
41
- each_pair(array){|key, val| map[key] = val}
42
- map
43
- end
44
-
45
18
  def for(*args, &block)
46
19
  first = args.first
47
20
 
@@ -99,11 +72,37 @@ class Map < Hash
99
72
 
100
73
  # instance constructor
101
74
  #
102
- attr_accessor :keys
75
+ def keys
76
+ @keys ||= []
77
+ end
103
78
 
104
79
  def initialize(*args, &block)
105
- super
106
- @keys = []
80
+ case args.size
81
+ when 0
82
+ super(&block)
83
+
84
+ when 1
85
+ case args.first
86
+ when Hash
87
+ initialize_from_hash(args.first)
88
+ when Array
89
+ initialize_from_array(args.first)
90
+ else
91
+ initialize_from_hash(args.first.to_hash)
92
+ end
93
+
94
+ else
95
+ initialize_from_array(args)
96
+ end
97
+ end
98
+
99
+ def initialize_from_hash(hash)
100
+ map.update(hash)
101
+ map.default = hash.default
102
+ end
103
+
104
+ def initialize_from_array(array)
105
+ Map.each_pair(array){|key, val| map[key] = val}
107
106
  end
108
107
 
109
108
  # support methods
@@ -112,8 +111,12 @@ class Map < Hash
112
111
  self
113
112
  end
114
113
 
114
+ def klass
115
+ self.class
116
+ end
117
+
115
118
  def map_for(hash)
116
- map = Map.new(hash)
119
+ map = klass.new(hash)
117
120
  map.default = hash.default
118
121
  map
119
122
  end
@@ -126,7 +129,7 @@ class Map < Hash
126
129
  return value.to_map if value.respond_to?(:to_map)
127
130
  case value
128
131
  when Hash
129
- Map.for(value)
132
+ klass.for(value)
130
133
  when Array
131
134
  value.map{|v| convert_value(v)}
132
135
  else
@@ -170,18 +173,16 @@ class Map < Hash
170
173
  alias_method '__get__', '[]' unless method_defined?('__get__')
171
174
  alias_method '__update__', 'update' unless method_defined?('__update__')
172
175
 
173
- def set(key, val)
176
+ def []=(key, val)
174
177
  key, val = convert(key, val)
175
- @keys.push(key) unless has_key?(key)
178
+ keys.push(key) unless has_key?(key)
176
179
  __set__(key, val)
177
180
  end
178
- alias_method 'store', 'set'
179
- alias_method '[]=', 'set'
181
+ alias_method 'store', '[]='
180
182
 
181
- def get(key)
182
- __get__(key)
183
+ def [](key)
184
+ __get__(convert_key(key))
183
185
  end
184
- alias_method '[]', 'get'
185
186
 
186
187
  def fetch(key, *args, &block)
187
188
  super(convert_key(key), *args, &block)
@@ -195,9 +196,7 @@ class Map < Hash
195
196
  alias_method 'member?', 'key?'
196
197
 
197
198
  def update(*args)
198
- Map.each_pair(*args) do |key, val|
199
- set(key, val)
200
- end
199
+ Map.each_pair(*args){|key, val| store(key, val)}
201
200
  self
202
201
  end
203
202
  alias_method 'merge!', 'update'
@@ -218,7 +217,7 @@ class Map < Hash
218
217
 
219
218
  def values
220
219
  array = []
221
- @keys.each{|key| array.push(self[key])}
220
+ keys.each{|key| array.push(self[key])}
222
221
  array
223
222
  end
224
223
  alias_method 'vals', 'values'
@@ -228,32 +227,32 @@ class Map < Hash
228
227
  end
229
228
 
230
229
  def first
231
- [@keys.first, self[@keys.first]]
230
+ [keys.first, self[keys.first]]
232
231
  end
233
232
 
234
233
  def last
235
- [@keys.last, self[@keys.last]]
234
+ [keys.last, self[keys.last]]
236
235
  end
237
236
 
238
237
  # iterator methods
239
238
  #
240
239
  def each_with_index
241
- @keys.each_with_index{|key, index| yield([key, self[key]], index)}
240
+ keys.each_with_index{|key, index| yield([key, self[key]], index)}
242
241
  self
243
242
  end
244
243
 
245
244
  def each_key
246
- @keys.each{|key| yield(key)}
245
+ keys.each{|key| yield(key)}
247
246
  self
248
247
  end
249
248
 
250
249
  def each_value
251
- @keys.each{|key| yield self[key]}
250
+ keys.each{|key| yield self[key]}
252
251
  self
253
252
  end
254
253
 
255
254
  def each
256
- @keys.each{|key| yield(key, self[key])}
255
+ keys.each{|key| yield(key, self[key])}
257
256
  self
258
257
  end
259
258
  alias_method 'each_pair', 'each'
@@ -262,18 +261,18 @@ class Map < Hash
262
261
  #
263
262
  def delete(key)
264
263
  key = convert_key(key)
265
- @keys.delete(key)
264
+ keys.delete(key)
266
265
  super(key)
267
266
  end
268
267
 
269
268
  def clear
270
- @keys = []
269
+ keys.clear
271
270
  super
272
271
  end
273
272
 
274
273
  def delete_if
275
274
  to_delete = []
276
- @keys.each{|key| to_delete.push(key) if yield(key)}
275
+ keys.each{|key| to_delete.push(key) if yield(key)}
277
276
  to_delete.each{|key| delete(key)}
278
277
  map
279
278
  end
@@ -287,7 +286,7 @@ class Map < Hash
287
286
  #
288
287
  def shift
289
288
  unless empty?
290
- key = @keys.first
289
+ key = keys.first
291
290
  val = delete(key)
292
291
  [key, val]
293
292
  end
@@ -298,7 +297,7 @@ class Map < Hash
298
297
  if key?(key)
299
298
  delete(key)
300
299
  else
301
- @keys.unshift(key)
300
+ keys.unshift(key)
302
301
  end
303
302
  __set__(key, val)
304
303
  end
@@ -310,7 +309,7 @@ class Map < Hash
310
309
  if key?(key)
311
310
  delete(key)
312
311
  else
313
- @keys.push(key)
312
+ keys.push(key)
314
313
  end
315
314
  __set__(key, val)
316
315
  end
@@ -319,7 +318,7 @@ class Map < Hash
319
318
 
320
319
  def pop
321
320
  unless empty?
322
- key = @keys.last
321
+ key = keys.last
323
322
  val = delete(key)
324
323
  [key, val]
325
324
  end
@@ -328,18 +327,23 @@ class Map < Hash
328
327
  # misc
329
328
  #
330
329
  def ==(hash)
331
- return false if @keys != hash.keys
330
+ return false unless(Map === hash)
331
+ return false if keys != hash.keys
332
332
  super hash
333
333
  end
334
334
 
335
+ def <=>(other)
336
+ keys <=> klass.for(other).keys
337
+ end
338
+
335
339
  def =~(hash)
336
- to_hash == Map.for(hash).to_hash
340
+ to_hash == klass.for(hash).to_hash
337
341
  end
338
342
 
339
343
  def invert
340
- inverted = Map.new
344
+ inverted = klass.new
341
345
  inverted.default = self.default
342
- @keys.each{|key| inverted[self[key]] = key }
346
+ keys.each{|key| inverted[self[key]] = key }
343
347
  inverted
344
348
  end
345
349
 
@@ -160,6 +160,21 @@ Testing Map do
160
160
  assert{ map =~ hash }
161
161
  end
162
162
 
163
+ testing 'that inheritence works without cycles' do
164
+ c = Class.new(Map){}
165
+ o = assert{ c.new }
166
+ assert{ Map === o }
167
+ end
168
+
169
+ testing 'equality' do
170
+ a = assert{ Map.new }
171
+ b = assert{ Map.new }
172
+ assert{ a == b}
173
+ assert{ a != 42 }
174
+ b[:k] = :v
175
+ assert{ a != b}
176
+ end
177
+
163
178
  protected
164
179
  def new_int_map(n = 1024)
165
180
  map = assert{ Map.new }
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: map
3
3
  version: !ruby/object:Gem::Version
4
- hash: 31
4
+ hash: 25
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
8
  - 2
9
- - 0
10
- version: 1.2.0
9
+ - 3
10
+ version: 1.2.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Ara T. Howard
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-10-05 00:00:00 -06:00
18
+ date: 2010-10-06 00:00:00 -06:00
19
19
  default_executable:
20
20
  dependencies: []
21
21