each() のイテレータのリセット方法

each() ってこういうやつである。

while (my ($k, $v) = each %hash) {
  say $k, $v;
}

ハッシュはそれぞれイテレータを持っていて、上記のように each() を次々に呼ぶことで違う値が返る。まずこれで問題が起きることは無いと思うが、まれに、while ループ中に last した場合や、ループの中以外で each() を使った場合に、イテレータが動いてしまっている場合がある。

10件のデータが登録されているハッシュに対して、3回 each() した後に while ループを抜けて、再度 while ループに入ると、今度は4件目からのスタートになるのだ。

リセットしたい場合、以下のように、ハッシュに対して keys を使ってやることでリセットできる。

keys %hash;

逆にループ中で keys を使ってしまうと、イテレータがリセットされ、無限ループしてしまうので注意が必要だ。