Прораммист написал скрипт для сортировки строк в соответствии с разными правилами:
sort.pl -i
должен упорядочивать строки без учета регистра,sort.pl -n
рассматривает строки как числа (т.е. 23 окажется раньше, чем 123),sort.pl -r
переставляет строки в случайном порядке.sort.pl (имя файла кликабельно, можно скачать исходник):
SortRules.pm (имя файла кликабельно, можно скачать исходник):
Однако сортировка как-то не работает.
Пример данных:
Скрипт не использует прагму warnings, ай-яй-яй!
А если бы программист ее включил, то увидел бы множество сообщений:
$SortRules::a
и $main::a
– это совсем разные переменные.
Дело в том, что sort
устанавливает для функции сравнеия
глобальные пакетные переменные $a
и $b
.
В нашем случае это $main::a
и $main::b
.
В то же время функции сравнения из пакета SortRules обращаются
к глобальным переменным своего пакета,
то есть к $SortRules::a
и $SortRules::b
.
Неудивительно, что функция сравнения выдавала предупреждения о неопределенных значениях!
Использовать в sort
сравнивающую функцию из другого пакета возможно,
просто для этого функцию надо объявить с прототипом ($$)
.
Пакет с функциями сравнения мог бы выглядеть так:
Цитата из perldoc -f sort
:
If the subroutine’s prototype is
($$)
, the elements to be compared are passed by reference in@_
, as for a normal subroutine. This is slower than unprototyped subroutines, where the elements to be compared are passed into the subroutine as the package global variables$a
and$b
.
Перевод:
Если у функции объявлен прототип
($$)
, то подлежащие сравнению элементы передаются по ссылке в массиве@_
, как для обычной функции. Это медленнее, чем фукнция без прототипа, в которую элемены для сравнения передаются в глобальных пакетных переменных$a
и$b
.
Мораль: всегда используйте прагмы strict
и warnings
,
обращайте внимание на предупреждения и читайте документацию (хотя бы иногда) ^_^
И еще: не пишите такой скрипт для сортировки.
Все сортировки, перечисленные в условии,
отлично выполняет утилита sort
с ключами -f
, -n
, -r
или вовсе без них.