Following on
moritz's
comment, I'll point out what is likely happening. Since your iterator is never reset and you are looping over a hash, every few times your call your subroutine (actual frequency depends on what letters you pass it), you have exhausted the iterator on your hash. Since your return statement only gets executed with a successful match, you exit your subroutine without explicitly specifying a value. Perl therefore returns the result of the last evaluation, which I think is the logical state of the
each statement - that is why you get zeros.
I'd also point out that $key and $value are not localized to the loop (probably ought to read my ($key, $value)). Assuming you are using and passing strict, this means you have actually created a closure and are possibly clobbering similarly named variables elsewhere in the code.