On Tue, Jun 24, 2008 at 5:53 PM, Rick DeNatale [email protected]
wrote:
Well, I haven’t dug into the implementation of Array#delete enough to fully
explain the results but.
And having now looked at the Ruby 1.8 implementation of Array#delete, I
think I know exactly what’s going on.
Here’s a pseudo-ruby translation of the C code:
class Array
def delete(obj)
i1 = i2 = 0
while i1 < self.length
e = self[i1]
unless e == obj
self[i2] = e
i2 += 1
end
i1 += 1
end
if i2 = self.length # We didn’t find any matches
return yield(obj) if block_given?
else
self.length = i2
end
end
def length=(l)
# A method to set the length of the array and make any necessary
internal adjustments
end
end
So, you start out with arr = $array = [1, 2, 3, aFoo, ‘b’]
And then call
arr.delete(1)
Now lets’s step through the delete method
i1 i2 self e e == 1
Action
0 0 [1, 2, 3, aFoo, ‘b’] 1 true so we
just
increment i1 giving
1 0 [1, 2, 3, aFoo, ‘b’] 2 false so we
change self[i0] and increment i2 giving
2 1 [2, 2, 3, aFoo, ‘b’] 3 false so we
change
self[i0] and increment i2 giving
3 2 [2, 3, 3, aFoo, ‘b’] Foo BANG! this clears
$array which is also self which is also arr, since all reference the
same
object. The state is now:
3 2 [nil, nil, nil, nil] Foo false
Foo#==
returns false so we set self[i2] = e and increment i2 giving:
4 3 [nil, nil, aFoo, nil]
And the loop ends and self.length = 3 adjusts things so that self == arr
$array == [nil, nil, aFoo]
–
Rick DeNatale
My blog on Ruby
http://talklikeaduck.denhaven2.com/