Then, and here is the problem, you remove $oldmessages! So the only message you have a record of is the last one. So the next time through, the first three messages are printed again, because they are no longer in the cache.
Good catch on the lost messages. Rather than your suggestion, however, I simply moved the line that places the message into the hash outside the if(!defined()) loop.
This means that only the messages that showed up are cached...the page should never return old messages, and my cache remains a usable size (actually, much smaller than yours! :) )
As for the repeat messages thing, that's a feature. Quite often repeated messages ARE repeats. With a limited cache, non-accidental repeat collisions should be rare.
Thanks for the help, it's much cleaner now with that one little change. Still not nicely packaged for an interface layer like yours is, but I admit to a small attachment to code I have written.