Ловушки Perl
Истории-страшилки про Perl-программиста, с подсказками и разоблачениями
Главная
О блоге
Об авторах
Почему?
rss
@perltrapcom
Программист написал функцию для классификации книг на интересные и не очень:
1 # в функцию передают ссылку на хеш с описанием книг,
2 # примерно так:
3 #{
4 # 'Alice in Wonderland' => {
5 # year => 1865,
6 # pages => 200,
7 # pictures => 1,
8 # conversations => 1,
9 # },
10 # 'Das Kapital' => {
11 # year => 1867,
12 # pages => 580,
13 # pictures => 0,
14 # conversation => 0,
15 # },
16 # ...
17 #}
18
19 sub classify_books
20 {
21 my $BOOKS = shift;
22 while(my ($title, $book) = each %$BOOKS) {
23 $book->{description} =
24 $book->{pictures} || $book->{conversation}
25 ? "an interesting book"
26 : "a boring book" ;
27 print "current state:\n".YAML::Dump($BOOKS);
28 }
29 }
Однако…
Функция работала долго. Очень долго.
Похоже было, что она собирается работать вечно.
Виновата “отладочная печать”, которую программист добавил в строке 27. Дело в том, что каждый хеш имеет (единственный) итератор, который используется функциями keys
, values
и each
. Функция Dump модуля YAML перебирает все элементы хеша (а как бы она иначе могла его сериализовать?), и тем самым сбрасывает этот итератор. Поэтому на каждой итерации цикла while в строчке 22 обработка хеша начинается сначала, и цикл никогда не заканчивался нормально.