On 23-Oct-07, at 10:02 AM, Jesús Gabriel y Galán wrote:
alias :enqueue :push
alias :dequeue :shift
Then you get Queue semantics and the start of the queue is the first
element in the Array :-). (you could do enqueue --> unshift, dequeue
–> pop if you rather have the first element of the queue the last in
You have to be really careful here. Push/pop and shift/unshift are
not the same functions working on opposite ends of the array, no
matter what it sounds like from the documentation.
There is an issue with shift that I think amounts to a bug. Shift/
unshift work at the beginning of the array, so shift conceptually
requires moving array elements around. Ruby (and other programming
languages too, specifically some implementations of Common Lisp)
optimise shift so as to not have to actually move anything in memory.
What it does is, more or less, to move the start of the array ‘right’
– so no movement but there is now some part of the array before the
start of the array. The bug is that Ruby doesn’t stomp on the cell of
the array that is being shifted before the start, and so that cell
still contains a reference to some object (and IT IS INVISIBLE).
You say this will never happen? or rarely? Well, it’s not ‘never’ for
sure, and ‘rarely’ doesn’t help much when you get caught by it. How
did I find out about it? Implementing a cache (the uncached stuff was
hanging around in memory, intermittently since unshift will re-use
the parts of the array before the start). I also found (and reported,
maybe even supplied a patch for) a problem in Mongrel’s thread
management code that was using shift. How did I debug it the first
time? Don’t ask.
I believe/hope that this will be fixed in some future version of Ruby.
This monkey patch fixes the problem, if this is how you want to solve
alias :clingy_shift :shift
self = nil
Bob H. – tumblelog at http://
Recursive Design Inc. – weblog at http://www.recursive.ca/
http://www.recursive.ca/ – works on http://www.raconteur.info/