map 5.5.0 → 5.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/a.rb +16 -5
  2. data/lib/map.rb +54 -67
  3. data/map.gemspec +1 -1
  4. data/test/map_test.rb +6 -17
  5. 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
- args = [0, 1, {:k=>:v, :a=>false}]
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.5.0' unless defined?(Version)
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
- return false unless key
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
- spec.each do |keys, value|
740
- keys = Array(keys).flatten
738
+ begin
739
+ spec.each do |keys, value|
740
+ keys = Array(keys).flatten
741
+ collection = self
742
+ key = keys.pop
741
743
 
742
- collection = self
743
-
744
- keys = key_for(keys)
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
- key = nil
769
+ return spec.values
770
+ end
771
+
772
+ def leaf_for(keys, options = {}, &block)
773
+ collection = self
774
+ key = nil
753
775
 
754
- keys.each_cons(2) do |a, b|
755
- a, b = alphanumeric_key_for(a), alphanumeric_key_for(b)
776
+ keys.each_cons(2) do |a, b|
777
+ a, b = alphanumeric_key_for(a), alphanumeric_key_for(b)
756
778
 
757
- exists = collection_has_key?(collection, a)
779
+ exists = collection_has_key?(collection, a)
758
780
 
759
- case b
760
- when Numeric
761
- #collection[a] ||= []
781
+ case b
782
+ when Numeric
783
+ if options[:autovivify]
762
784
  collection[a] = [] unless exists
763
- raise(IndexError, "(#{ collection.inspect })[#{ a.inspect }]=#{ value.inspect }") unless collection[a].is_a?(Array)
785
+ end
786
+ raise(IndexError, "(#{ collection.inspect })[#{ a.inspect }][#{ b.inspect }]") unless collection[a].is_a?(Array)
764
787
 
765
- when String, Symbol
766
- #collection[a] ||= {}
767
- collection[a] = {} unless exists
768
- raise(IndexError, "(#{ collection.inspect })[#{ a.inspect }]=#{ value.inspect }") unless collection[a].is_a?(Hash)
769
- end
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[key] = value
795
+ collection = collection[a]
796
+ key = b
775
797
  end
776
798
 
777
- return spec.values
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 unless dot_keys?
878
- self.dot_key_for(*keys)
869
+ return keys.flatten
879
870
  end
880
871
 
881
872
  def key_for(*keys)
882
- if dot_keys?
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
@@ -3,7 +3,7 @@
3
3
 
4
4
  Gem::Specification::new do |spec|
5
5
  spec.name = "map"
6
- spec.version = "5.5.0"
6
+ spec.version = "5.6.1"
7
7
  spec.platform = Gem::Platform::RUBY
8
8
  spec.summary = "map"
9
9
  spec.description = "description: map kicks the ass"
@@ -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?(Hash) }
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.5.0
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-03-29 00:00:00.000000000 Z
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