On 24-Oct-07, at 9:54 AM, Todd Benson wrote:

> On 10/24/07, Bob Hutchison <hutch / recursive.ca> wrote:
>>
>> On 24-Oct-07, at 9:03 AM, Todd Benson wrote:
>>
>>>   def dequeue
>>>     @list.shift
>>>   end
>>
>> Save yourself some grief, do it this way:
>>
>> def dequeue
>>    tmp = @list[0]
>>    @list[0] = nil
>>    @list.shift
>>    tmp
>> end
>>
>> Cheers,
>> Bob
>
> Bob, I can only guess that the grief you are talking about has
> something to do with memory management, but I don't see it.

It has to do with an optimisation in the implementation of shift  
(there's a series of posts regarding this earlier in this thread). In  
brief, shift optimises itself by 'shifting' the start of the array  
rather than shifting the contents of the array. The effect is that  
using shift leaves an old part of the array in front of the start of  
the array (but you cannot access it). The problem is that the shift  
implementation doesn't 'clear' the original 0th element, so it is  
still in memory, is not accessible, but the garbage collector can see  
it. In effect, the object referenced isn't collected because there is  
a reference. This is a memory leak. Sooner or later it'll get fixed  
up, but sometimes it really is later.

>
> Can someone explain -- with the code above -- why tmp does in fact
> _not_ take on NilClass?  I think it would be good info for newbies.
>

In the above code, the shift method, through an involved but hidden  
technique implemented by Ruby, arranges for the 0th element of the  
list to 'disappear', for the original @list[1] to become @list[0] and  
so on, for the array size to be reduced by one, and returns the  
original @list[0].

So, tmp 'remembers' the original @list[0]. The '@list[0] = nil'  
removes the reference to what is now in tmp, and @list.shift makes  
the original @list[0] 'disappear', and the last reference to tmp  
returns it as the result of the method.

Unfortunately it isn't as simple as everyone would like it to be.  
But, as I've mentioned elsewhere, this will all go away in some  
future version of Ruby. Already Ruby 1.8.5 is much better than 1.8.4

Cheers,
Bob


> Todd
>

----
Bob Hutchison                  -- tumblelog at http:// 
www.recursive.ca/so/
Recursive Design Inc.          -- weblog at http://www.recursive.ca/ 
hutch
http://www.recursive.ca/       -- works on http://www.raconteur.info/ 
cms-for-static-content/home/