Suppose I start a worker thread, like so:

require 'thread'
queue = Queue.new

Thread.new do
  loop do
    # Suppose this does something useful...
    puts queue.pop
  end
end

And I start sending things to that queue:

queue.push 'Hello, world!'
queue.push '(from inside the thread)'

...and so on.

Now, at some point, the queue will fall out of scope -- at which point, I'm 
obviously not going to push anything onto it. It's also the only way to talk 
to the thread, so the thread isn't going to be doing anything useful at this 
point.

I'd like to collect that thread, but, of course, that's really impossible. 
After all, the loop will never end, so the thread will never exit normally. 
Without solving the Halting Problem, Ruby can't know that the thread won't do 
anything useful, even if nothing else refers to it -- maybe it will push 
something onto that queue, after all.

Now, I know the logical solution to this particular problem:

Thread.new do
  until (item = queue.pop).nil?
    puts item
  end
end

But then, I have to remember to send that message just before the queue goes 
out of scope:

queue.push nil

Is there any way to handle this gracefully? For example: Any way to tell that 
the queue has gone out of scope, there? Or any way to fire any code right 
before an object is collected?

Or do I always have to remember to kill that thread explicitly, somehow -- by 
sending that nil, for example?