Aaron said:
The workaround to eliminate leakage with array.shift works except that
shift no longer returns the shifted element and instead returns nil
The following class allows shift to work normally without the leakage
.... I know it is only a temporary work around until the ruby developers
get around to fix the c code
#### Array#shift ###############
class Array
alias

rig_shift :shift
def shift
return nil if self.empty?
ret = self[0]
self[0] = nil
self.orig_shift
return ret
end
end
###### code to show that the leakage has been eliminated
separator = "---"
o_count = Hash.new(0)
GC.start
ObjectSpace.each_object { |o| o_count[o.class] += 1 }
o_count.sort_by { |k,v| -v}.each { |k,v| puts "#{k}: #{v}" }
o_count = nil
puts separator
array = []
10.times { array << "foo" }
10.times { array.pop } # Change this to shift to see a leak
o_count = Hash.new(0)
GC.start
ObjectSpace.each_object { |o| o_count[o.class] += 1 }
o_count.sort_by { |k,v| -v}.each { |k,v| puts "#{k}: #{v}" }
array = nil
o_count = nil
puts separator
array = []
10.times { array << "foo" }
10.times { array.shift } # Change this to shift to see a leak
o_count = Hash.new(0)
GC.start
ObjectSpace.each_object { |o| o_count[o.class] += 1 }
o_count.sort_by { |k,v| -v}.each { |k,v| puts "#{k}: #{v}" }
__END__
####### test results only pertinent data shown
NEW shift method
before pop after pop
before shift after shift
String: 1746 1764 1764
Array: 70 71 72
OLD shift methed -- Class Array commented out
before pop after pop
before shift after shift
String: 1746 1764 1774
Array: 70 71 72
################## code to show that Array#shift behaves as described
in the ri documentation
class Array
alias

rig_shift :shift
def shift
return nil if self.empty?
ret = self[0]
self[0] = nil
self.orig_shift
return ret
end
end
a = (1..5).to_a
1.upto(10) do |i|
x = a.shift
puts "#{i}: \tx: #{x.inspect} \ta: #{a.inspect}"
end
__END__
1: x: 1 a: [2, 3, 4, 5]
2: x: 2 a: [3, 4, 5]
3: x: 3 a: [4, 5]
4: x: 4 a: [5]
5: x: 5 a: []
6: x: nil a: []
7: x: nil a: []
8: x: nil a: []
9: x: nil a: []
10: x: nil a: []