Все задачи

Кому нужны книжки без картинок?

08 Apr 2013

Программист написал функцию для классификации книг на интересные и не очень:

 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 }

Однако…

### Подсказка

Показать

Функция работала долго. Очень долго.

Подсказка-2

Показать

Похоже было, что она собирается работать вечно.

Разоблачение

Показать

Виновата “отладочная печать”, которую программист добавил в строке 27. Дело в том, что каждый хеш имеет (единственный) итератор, который используется функциями keys, values и each. Функция Dump модуля YAML перебирает все элементы хеша (а как бы она иначе могла его сериализовать?), и тем самым сбрасывает этот итератор. Поэтому на каждой итерации цикла while в строчке 22 обработка хеша начинается сначала, и цикл никогда не заканчивался нормально.

См. также http://perldoc.perl.org/functions/each.html