map 5.5.0 → 5.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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