I'm going to have to disagree with you categorically.
You do control the each iterator. You just don't explicitly create it. It's very simple to reset the iterator, should you choose, with a void keys call. I do not consider this a hack.
In many Perls, lazy lists aren't fully implemented in for(keys%h). This means that large lists can grow your RAM unnecessarily.
When using a tied datastructure, such as from DBM::Deep, each() is strongly preferred due to the way tie implements hash iteration. TIEHASH provides FIRSTKEY and NEXTKEY($current_key). each() calls the methods each iteration and is generally nice. keys() has to call FIRSTKEY, then NEXTKEY($current_key) successively until it returns undef. This can be extremely costly.
My criteria for good software:
Does it work?
Can someone else come in, make a change, and be reasonably certain no bugs were introduced?