Ловушки Perl
Истории-страшилки про Perl-программиста, с подсказками и разоблачениями
Главная
О блоге
Об авторах
Почему?
rss
@perltrapcom
Программист писал скрипт, который парсит описания книг из файла. Данные выглядят примерно так:
17914003 Льюс Кэрролл. Алиса в стране чудес
7459350 Karl Marx. Das Kapital
3669011 Damian Conway. Perl Best Practices
7304332 Лев Толстой. Война и мир
7364216 Индийские сказки
Получился вот такой код:
use strict;
use warnings;
# в файле книги записаны в формате:
# <id> <автор>. <название>
# автора может не быть
my @books;
while (my $title = <>) {
chomp $title;
next if $title eq '';
$title =~ s/^([0-9]+)\s*//;
my $id = $1;
$title =~ s/^(.+?)\.\s*//;
my $author = $1 || '';
push @books, {
id => $id,
title => $title,
author => $author,
};
}
# ...
Все хорошо, но у некоторых книг были проблемы с авторами…
Кстати, про этого программиста есть еще история: Книжки без картинок.
У некоторых книг вместо автора проставлялись какие-то числа.
Программист добавил отладочную печать:
print join "\n", map {"$_->{title} - $_->{author}"} @books;
Результат:
Алиса в стране чудес - Льюс Кэрролл
Das Kapital - Karl Marx
Perl Best Practices - Damian Conway
Война и мир - Лев Толстой
Индийские сказки - 7364216
Проблема в том, что переменные $1
, $2
и т.п.
не сбрасываются, если очередное сопоставление с регулярным
выражением не поймало ни одной группы.
Поэтому даже если у книги не был указан автор,
в переменной $1
все равно содержалась непустая строчка,
оставшаяся от предыдущего успешного сопоставления (в нашем случае – от поиска id книги).