map 4.1.0 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/lib/map.rb +56 -7
  2. data/map.gemspec +2 -1
  3. data/test/leak.rb +60 -0
  4. data/test/map_test.rb +30 -0
  5. metadata +5 -4
data/lib/map.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  class Map < Hash
2
- Version = '4.1.0' unless defined?(Version)
2
+ Version = '4.2.0' unless defined?(Version)
3
3
  Load = Kernel.method(:load) unless defined?(Load)
4
4
 
5
5
  class << Map
@@ -683,20 +683,21 @@ class Map < Hash
683
683
 
684
684
  def set(*args)
685
685
  if args.size == 1 and args.first.is_a?(Hash)
686
- options = args.shift
686
+ spec = args.shift
687
687
  else
688
- options = {}
688
+ spec = {}
689
689
  value = args.pop
690
690
  keys = args
691
- options[keys] = value
691
+ spec[keys] = value
692
692
  end
693
693
 
694
- options.each do |keys, value|
694
+ spec.each do |keys, value|
695
695
  keys = Array(keys).flatten
696
696
 
697
697
  collection = self
698
698
  if keys.size <= 1
699
- collection[keys.first] = value
699
+ key = keys.first
700
+ collection[key] = value
700
701
  next
701
702
  end
702
703
 
@@ -721,7 +722,55 @@ class Map < Hash
721
722
  collection[key] = value
722
723
  end
723
724
 
724
- return options.values
725
+ return spec.values
726
+ end
727
+
728
+ def rm(*args)
729
+ paths, path = args.partition{|arg| arg.is_a?(Array)}
730
+ paths.push(path)
731
+
732
+ paths.each do |path|
733
+ if path.size == 1
734
+ delete(*path)
735
+ next
736
+ end
737
+
738
+ branch, leaf = path[0..-2], path[-1]
739
+ collection = get(branch)
740
+
741
+ case collection
742
+ when Hash
743
+ key = leaf
744
+ collection.delete(key)
745
+ when Array
746
+ index = leaf
747
+ collection.delete_at(index)
748
+ else
749
+ raise(IndexError, "(#{ collection.inspect }).rm(#{ path.inspect })")
750
+ end
751
+ end
752
+ paths
753
+ end
754
+
755
+ def forcing(forcing=nil, &block)
756
+ @forcing ||= nil
757
+
758
+ if block
759
+ begin
760
+ previous = @forcing
761
+ @forcing = forcing
762
+ block.call()
763
+ ensure
764
+ @forcing = previous
765
+ end
766
+ else
767
+ @forcing
768
+ end
769
+ end
770
+
771
+ def forcing?(forcing=nil)
772
+ @forcing ||= nil
773
+ @forcing == forcing
725
774
  end
726
775
 
727
776
  def apply(other)
@@ -3,7 +3,7 @@
3
3
 
4
4
  Gem::Specification::new do |spec|
5
5
  spec.name = "map"
6
- spec.version = "4.1.0"
6
+ spec.version = "4.2.0"
7
7
  spec.platform = Gem::Platform::RUBY
8
8
  spec.summary = "map"
9
9
  spec.description = "description: map kicks the ass"
@@ -19,6 +19,7 @@ Gem::Specification::new do |spec|
19
19
  "lib/map/struct.rb",
20
20
  "map.gemspec",
21
21
  "test",
22
+ "test/leak.rb",
22
23
  "test/lib",
23
24
  "test/lib/testing.rb",
24
25
  "test/map_test.rb"]
@@ -0,0 +1,60 @@
1
+ require 'map'
2
+
3
+ ##
4
+ #
5
+ gc =
6
+ lambda do
7
+ 10.times{ GC.start }
8
+ end
9
+
10
+ leak =
11
+ lambda do
12
+ 100.times do
13
+ m = Map.new
14
+
15
+ 1000.times do |i|
16
+ m[rand.to_s] = rand
17
+ end
18
+ end
19
+
20
+ gc.call()
21
+ end
22
+
23
+ ##
24
+ #
25
+
26
+
27
+ leak.call()
28
+ before = Process.size
29
+
30
+
31
+ leak.call()
32
+ after = Process.size
33
+
34
+ delta = [after.first - before.first, after.last - before.last]
35
+
36
+ p :before => before
37
+ p :after => after
38
+ p :delta => delta
39
+
40
+
41
+ ##
42
+ #
43
+ BEGIN {
44
+
45
+ module Process
46
+ def self.size pid = Process.pid
47
+ stdout = `ps wwwux -p #{ pid }`.split(%r/\n/)
48
+ vsize, rsize = stdout.last.split(%r/\s+/)[4,2].map{|i| i.to_i}
49
+ end
50
+
51
+ def self.vsize
52
+ size.first.to_i
53
+ end
54
+
55
+ def self.rsize
56
+ size.last.to_i
57
+ end
58
+ end
59
+
60
+ }
@@ -494,6 +494,36 @@ Testing Map do
494
494
  end
495
495
  end
496
496
 
497
+ testing 'that maps a clever little rm operator' do
498
+ map = Map.new
499
+ map.set :a, :b, 42
500
+ map.set :x, :y, 42
501
+ map.set :x, :z, 42
502
+ map.set :array, [0,1,2]
503
+
504
+ assert{ map.rm(:x, :y) }
505
+ assert{ map.get(:x) =~ {:z => 42} }
506
+
507
+ assert{ map.rm(:a, :b) }
508
+ assert{ map.get(:a) =~ {} }
509
+
510
+ assert{ map.rm(:array, 0) }
511
+ assert{ map.get(:array) == [1,2] }
512
+ assert{ map.rm(:array, 1) }
513
+ assert{ map.get(:array) == [1] }
514
+ assert{ map.rm(:array, 0) }
515
+ assert{ map.get(:array) == [] }
516
+
517
+ assert{ map.rm(:array) }
518
+ assert{ map.get(:array).nil? }
519
+
520
+ assert{ map.rm(:a) }
521
+ assert{ map.get(:a).nil? }
522
+
523
+ assert{ map.rm(:x) }
524
+ assert{ map.get(:x).nil? }
525
+ end
526
+
497
527
  protected
498
528
  def new_int_map(n = 1024)
499
529
  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: 59
4
+ hash: 55
5
5
  prerelease:
6
6
  segments:
7
7
  - 4
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 4.1.0
10
+ version: 4.2.0
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: 2011-06-03 00:00:00 -06:00
18
+ date: 2011-06-08 00:00:00 -06:00
19
19
  default_executable:
20
20
  dependencies: []
21
21
 
@@ -35,6 +35,7 @@ files:
35
35
  - lib/map/options.rb
36
36
  - lib/map/struct.rb
37
37
  - map.gemspec
38
+ - test/leak.rb
38
39
  - test/lib/testing.rb
39
40
  - test/map_test.rb
40
41
  has_rdoc: true