Читаете ли вы perlop?
Опубликовано 03.06.2009
Еще немного про perl. Перелистывая Perl Cookbook, вдруг осознал, что никогда не задумывался о возможностях оператора диапазона «..
«. То есть, конечно, понятно, что в списковом контексте он вернет список значений от левого операнда до правого и конструкция foreach(1 .. 5)
превратится в начало натурального ряда. А вот про то, что в скалярном контексте этот оператор ведет себя наподобие диапазона в sed, я не знал. Например, часто возникающая задача «сделать что-то с данными между открывающей и закрывающей строкой» решается просто и элегантно:
perl -ne 'print if /<Directory /i .. /<\/Directory>/i' httpd.conf
Благодаря кажущейся простоте этого оператора (зачем читать доку про такие элементарные вещи, если в первом попавшемся букваре по перлу написано, что именно делает этот оператор) редкая птица удосужится ознакомиться с описанием ..
в perlop, что и приводит к подобным открытиям.
Не последнюю роль тут играет и местами довольно сложный язык документации. Но мир меняется к лучшему и недавно на translated.by в рамках проекта pod2-ru под руководством Анатолия Шарифулина народ принялся за перевод perldoc. К настоящему моменту уже переведены: perlbook, perldoc, perlpragma, perlstyle; на подходе perlintro и в процессе одна из центральных страниц документации — perlfunc. Также переведена примерно половина perlboot. Так что если есть желание и возможность помочь в переводе документации perl, присоединяйтесь к любому из этих переводов или начинайте свой. Даже с минимальными знаниями английского языка вы можете помочь в качестве редактора или корректора. В общем, внесите уже свой вклад в open source :)
Прикольная фишка, пасиб :). Только где-то в том числе видать из-за таких вот жемчужин мну лично на перле только разве что похожие такие вот one-liners пишет, не более :).
Еще как читаем. Только что написал в своем проекте:
# fire and forget
push( @threads, threads->create( \&_getOnlineStatus ) )
for 1 .. $self->_maxThreads;
Отвлекся и увидел новое сообщение в RSS-ридере. Подобные языковые конструкции уже давно въелись в мозг.
ну так это списковый контекст, а я немного не о том
Спасибо, я об этом не знал. Поражаюсь гениальности Ларри Уолла. Это же надо было так сделать что и в том и другом случае этот оператор оставался оператором диапазона несмотря на совершенно различное поведение. Думаю этому может найтись множество применений.
Раньше, когда нужно было как-то обработать текст заключенный внутрь другого текста, я использовал переменную-флаг, которая говорила, что текущий текст необходимо обрабатывать, теперь же это лишнее.
Также, если операндом этого оператора является цифра, то она воспринимается как текущий номер строки последнего открытого файлового дескриптора (тоже что $.). Вот так можно вывести первые десять строк файла:
perl -ne’print if 1 .. 10′ /etc/passwd
Кроме того, в скалярном контексте оператор «..», в случае срабатывания, возвращает не просто «истина», а число, говорящее нам сколько раз он уже эту истину успел вернуть с момента последнего «включения». А если это срабатывание было последним, то оператор вернет соответствующее число + E0 (напр. 26E0). Так можно сделать свою нумерацию в каждой группе строк:
perl -ne’$mn = /<Directory/i .. //i; print int($mn) .» «. $_ if $mn’ httpd.conf
Явное преобразование с помощью int() здесь нужно, чтобы отбросить часть с «E0″.
Если оператор «..» прошлый раз вернул «ложь», а сейчас левый операнд вернул «истину», а правый «ложь» , то в следующий раз он вернет «ложь» (и левый и правый операнды в таком случае проверяються одновременно). Если хочется чтобы при возвращении левого операнда истины» правый операнд не проверялся, то используют оператор «…».
Да, действительно элегантная фишка. Особенно в контексте однострочников.
Я тоже использовал вспомогательные переменные «флаги» для обработки куска текста.
Теперь буду использовать диапазон.
Спасибо.