map 5.5.0 → 5.6.1
Sign up to get free protection for your applications and to get access to all the features.
- data/a.rb +16 -5
- data/lib/map.rb +54 -67
- data/map.gemspec +1 -1
- data/test/map_test.rb +6 -17
- metadata +2 -2
data/a.rb
CHANGED
@@ -1,9 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
1
3
|
# -*- encoding : utf-8 -*-
|
2
|
-
require './lib/map.rb'
|
3
4
|
|
4
|
-
|
5
|
+
def assert(&block)
|
6
|
+
block.call
|
7
|
+
end
|
8
|
+
|
9
|
+
m = Map.new
|
10
|
+
m.set(:a, :b, :c, 42)
|
11
|
+
p m.get(:a, :b, 0)
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
m = Map.new
|
16
|
+
m.set(:a, 0, 42)
|
17
|
+
p m.get(:a, :b, 0)
|
18
|
+
|
5
19
|
|
6
|
-
opts = Map.options_for!(args)
|
7
20
|
|
8
|
-
p args
|
9
|
-
p opts
|
data/lib/map.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding : utf-8 -*-
|
2
2
|
class Map < Hash
|
3
|
-
Version = '5.
|
3
|
+
Version = '5.6.1' unless defined?(Version)
|
4
4
|
Load = Kernel.method(:load) unless defined?(Load)
|
5
5
|
|
6
6
|
class << Map
|
@@ -721,8 +721,7 @@ class Map < Hash
|
|
721
721
|
when Hash
|
722
722
|
collection.has_key?(key)
|
723
723
|
when Array
|
724
|
-
|
725
|
-
(0...collection.size).include?(Integer(key))
|
724
|
+
(0...collection.size).include?((Integer(key) rescue -1))
|
726
725
|
end
|
727
726
|
end
|
728
727
|
|
@@ -736,45 +735,70 @@ class Map < Hash
|
|
736
735
|
spec[keys] = value
|
737
736
|
end
|
738
737
|
|
739
|
-
|
740
|
-
|
738
|
+
begin
|
739
|
+
spec.each do |keys, value|
|
740
|
+
keys = Array(keys).flatten
|
741
|
+
collection = self
|
742
|
+
key = keys.pop
|
741
743
|
|
742
|
-
|
743
|
-
|
744
|
-
|
744
|
+
while((k = keys.shift)) do
|
745
|
+
k = alphanumeric_key_for(k)
|
746
|
+
collection = collection[k]
|
747
|
+
end
|
745
748
|
|
746
|
-
if keys.size <= 1
|
747
|
-
key = keys.first
|
748
749
|
collection[key] = value
|
749
|
-
next
|
750
750
|
end
|
751
|
+
rescue
|
752
|
+
spec.each do |keys, value|
|
753
|
+
keys = Array(keys).flatten
|
754
|
+
|
755
|
+
collection = self
|
756
|
+
|
757
|
+
if keys.size <= 1
|
758
|
+
key = keys.first
|
759
|
+
collection[key] = value
|
760
|
+
next
|
761
|
+
end
|
762
|
+
|
763
|
+
leaf_for(keys, :autovivify => true) do |leaf, key|
|
764
|
+
leaf[key] = value
|
765
|
+
end
|
766
|
+
end
|
767
|
+
end
|
751
768
|
|
752
|
-
|
769
|
+
return spec.values
|
770
|
+
end
|
771
|
+
|
772
|
+
def leaf_for(keys, options = {}, &block)
|
773
|
+
collection = self
|
774
|
+
key = nil
|
753
775
|
|
754
|
-
|
755
|
-
|
776
|
+
keys.each_cons(2) do |a, b|
|
777
|
+
a, b = alphanumeric_key_for(a), alphanumeric_key_for(b)
|
756
778
|
|
757
|
-
|
779
|
+
exists = collection_has_key?(collection, a)
|
758
780
|
|
759
|
-
|
760
|
-
|
761
|
-
|
781
|
+
case b
|
782
|
+
when Numeric
|
783
|
+
if options[:autovivify]
|
762
784
|
collection[a] = [] unless exists
|
763
|
-
|
785
|
+
end
|
786
|
+
raise(IndexError, "(#{ collection.inspect })[#{ a.inspect }][#{ b.inspect }]") unless collection[a].is_a?(Array)
|
764
787
|
|
765
|
-
|
766
|
-
|
767
|
-
collection[a] =
|
768
|
-
|
769
|
-
|
770
|
-
collection = collection[a]
|
771
|
-
key = b
|
788
|
+
when String, Symbol
|
789
|
+
if options[:autovivify]
|
790
|
+
collection[a] = Map.new unless exists
|
791
|
+
end
|
792
|
+
raise(IndexError, "(#{ collection.inspect })[#{ a.inspect }][#{ b.inspect }]") unless collection[a].is_a?(Map)
|
772
793
|
end
|
773
794
|
|
774
|
-
collection
|
795
|
+
collection = collection[a]
|
796
|
+
key = b
|
775
797
|
end
|
776
798
|
|
777
|
-
|
799
|
+
leaf = collection
|
800
|
+
|
801
|
+
block ? block.call(leaf, key) : [leaf, key]
|
778
802
|
end
|
779
803
|
|
780
804
|
def rm(*args)
|
@@ -841,49 +865,12 @@ class Map < Hash
|
|
841
865
|
Map.alphanumeric_key_for(key)
|
842
866
|
end
|
843
867
|
|
844
|
-
## key path support
|
845
|
-
#
|
846
|
-
def self.dot_key_for(*keys)
|
847
|
-
dot = keys.compact.flatten.join('.')
|
848
|
-
dot.split(%r/\s*[,.]\s*/).map{|part| part =~ %r/^\d+$/ ? Integer(part) : part}
|
849
|
-
end
|
850
|
-
|
851
|
-
def self.dot_keys
|
852
|
-
@@dot_keys = {} unless defined?(@@dot_keys)
|
853
|
-
@@dot_keys
|
854
|
-
end
|
855
|
-
|
856
|
-
def self.dot_keys?
|
857
|
-
ancestors.each do |ancestor|
|
858
|
-
return dot_keys[ancestor] if dot_keys.has_key?(ancestor)
|
859
|
-
end
|
860
|
-
false
|
861
|
-
end
|
862
|
-
|
863
|
-
def dot_keys?
|
864
|
-
@dot_keys = false unless defined?(@dot_keys)
|
865
|
-
@dot_keys
|
866
|
-
end
|
867
|
-
|
868
|
-
def self.dot_keys!(boolean = true)
|
869
|
-
dot_keys[self] = !!boolean
|
870
|
-
end
|
871
|
-
|
872
|
-
def dot_keys!(boolean = true)
|
873
|
-
@dot_keys = !!boolean
|
874
|
-
end
|
875
|
-
|
876
868
|
def self.key_for(*keys)
|
877
|
-
return keys.flatten
|
878
|
-
self.dot_key_for(*keys)
|
869
|
+
return keys.flatten
|
879
870
|
end
|
880
871
|
|
881
872
|
def key_for(*keys)
|
882
|
-
|
883
|
-
self.class.dot_key_for(*keys)
|
884
|
-
else
|
885
|
-
self.class.key_for(*keys)
|
886
|
-
end
|
873
|
+
self.class.key_for(*keys)
|
887
874
|
end
|
888
875
|
|
889
876
|
## TODO - technically this returns only leaves so the name isn't *quite* right. re-factor for 3.0
|
data/map.gemspec
CHANGED
data/test/map_test.rb
CHANGED
@@ -349,26 +349,10 @@ Testing Map do
|
|
349
349
|
assert{ m[:A].is_a?(Array) }
|
350
350
|
assert{ m[:A].size == 3}
|
351
351
|
assert{ m[:A][2] == 'forty-two' }
|
352
|
-
assert{ m[:x][:y].is_a?(
|
352
|
+
assert{ m[:x][:y].is_a?(Map) }
|
353
353
|
assert{ m[:x][:y][:z] == 42.0 }
|
354
354
|
end
|
355
355
|
|
356
|
-
testing 'that maps can support compound key/val setting via key.dot notation' do
|
357
|
-
m = Class.new(Map){ dot_keys! }.new
|
358
|
-
assert{ m.set('a.b.c', 42) }
|
359
|
-
assert{ m[:a][:b][:c] == 42 }
|
360
|
-
assert{ m.get('a.b.c') == 42 }
|
361
|
-
assert{ m.set('x.y.z' => 42.0, 'A.2' => 'forty-two') }
|
362
|
-
assert{ m[:A].is_a?(Array) }
|
363
|
-
assert{ m[:A].size == 3}
|
364
|
-
assert{ m[:A][2] == 'forty-two' }
|
365
|
-
assert{ m[:x][:y].is_a?(Hash) }
|
366
|
-
assert{ m[:x][:y][:z] == 42.0 }
|
367
|
-
assert{ m.has?('a.b.c') }
|
368
|
-
assert{ m.has?('x.y.z') }
|
369
|
-
assert{ m.has?('A.2') }
|
370
|
-
end
|
371
|
-
|
372
356
|
testing 'that Map#get supports providing a default value in a block' do
|
373
357
|
m = Map.new
|
374
358
|
m.set(:a, :b, :c, 42)
|
@@ -402,6 +386,11 @@ Testing Map do
|
|
402
386
|
assert{ m.apply(defaults) }
|
403
387
|
assert{ m[:array] == [0,1,2] }
|
404
388
|
assert{ m[:hash] =~ {:a => false, :b => true, :c => 42} }
|
389
|
+
|
390
|
+
m = Map.new
|
391
|
+
assert{ m.apply :key => [{:key => :val}] }
|
392
|
+
assert{ m[:key].is_a?(Array) }
|
393
|
+
assert{ m[:key][0].is_a?(Map) }
|
405
394
|
end
|
406
395
|
|
407
396
|
testing 'that maps support depth_first_each' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: map
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.6.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-05-18 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! 'description: map kicks the ass'
|
15
15
|
email: ara.t.howard@gmail.com
|