Программист оказался вовлеченным в старый проект с большим количеством кода на Perl.
В числе прочего программист нашел такой код для выделения первого поля
из стандартного входного потока (что-то вроде awk '{print $1}'
):
И вот что интересно: этот код нормально работал, а потом вдруг перестал. В сам код никаких изменений не вносили, входные данные тоже остались прежними.
Почему работал этот код? Что с ним случилось потом?
Код не менялся, данные тоже. Менялся perl.
Вплоть до версии 5.10 split
в скалярном контексте не только возвращал
количество полей, на которые он разбил строку, но и записывал полученные
поля в массив @_
.
Впрочем, пользоваться этим поведеним документация не рекомендовала:
In scalar context, returns the number of fields found. In scalar and void context it splits into the @_ array. Use of split in scalar and void context is deprecated, however, because it clobbers your subroutine arguments.
В скалярном контексте возвращает количество найденных полей. В скалярном и пустом контексте записывает результат в массив
@_
Однако, использованиеsplit
в скалярном и пустом контексте строго не рекомендуется, потому что оно портит аргументы функций
Именно благодаря этому поведению код из задачи работал на старых версиях perl.
Начиная с версии 5.12 split
не записывает свой результат в @_
,
присваивание надо выполнять самостоятельно:
Самое полное и точное объяснение проблемы прислал наш читатель Тигран Оганесян. Класс!