Как стать автором
Обновить

JAPH — perl-скрипты, которые показывают на что способен PERL в умелых руках

Время на прочтение3 мин
Количество просмотров1.3K
[введение]
Практически любой программист, сталкивавшийся когда-либо с ВЕЛИКОМ ЯЗЫКОМ ПРОГРАММИРОВАНИЯ — PERL, но не пишущий на нем регулярно, считает, что он очень сложный и запутанный! Практически не понятный простому обывателю! Своей статьей хотел бы подтвердить этот миф и рассказать о таком явлении как JAPH.

[кульминация]
JAPH — это аббревиатура, расшифровывается как «Just Another Perl Hacker», введенная в обиход в далеком 1990 году одним широко известный perl-хакером Рэндалом Шварцом (Randal Schwartz aka merlyn). «Но при чем тут perl?» — спросите вы. Ответить на этот вопрос лучше всего одним из самых известный japh'ов, который, на мой взгляд, демонстрирует суть этого явления!

print "Just another Perl hacker," if "you can't think of anything better..."

Стоит вам запустить этот код как на экране вы увидите «заветный» слова «Just another Perl hacker,» :-) (Сразу хотел бы оговориться по поводу запитой после слова «hacker». На сколько мне известно, она была в первых скриптах merlyn. Наверное, автор хотел подчеркнуть некую не завершенность, подтолкнуть тех кто это увидит к продолжению. В последствии же она исчезла :-) ) Не правда ли странный скрипт? состоит все во лишь из двух операторов! сначала print, и только потом if, и ни какой; между ними! Казалось бы он не должен работать, но он работает! и работает правильно! В одной строчке скрыто сразу два хака, заложенных в perl. 1-й это то что в условном операторе if в качестве аргумента может быть все что угодно и условие будет истинным, если аргумент не будет 0 или undef(не определенное значение). 2-й это положение операторов if и print. Если в результате проверки условия в if'e должна выполниться одна команда, то она может располагаться в коде перед if'м. Это придает коду более компактный вид. К слову, такая форма записи допустима для любых оператором условия и перечисления.
Это один из самых простых примеров JAPH, существуют и более интересные:

''=~('('.'?' . '{'.(
'/'.'/'.')'.'.'.'/'.
'`'.'|'.'`'.'.'.'.'.
'/'.'`'.'`'.'.'.'/'.
'/'.'('.':'.'/'.'`'.
'~'.':'.'/'.','.'`'.
'`'.':'.'>'.'+'.':'.
'/'.'|'^'_'.']'.'@'.
'@'.'['.'@'.'['.'*'.
'['.']'.'['.'@'.'!'.
'@'.'@'.'['.'@'.'_'.
']'.'@'.'.'.'_'.']'.
'@'.'@'.'('.'['.']'.
'@'.'_'.']'.'[').','
.'$' .'/'.'}'.')' );

(Monolith by boo) Это прямоугольник, в котором НЕТ букв. Угадайте, что выводит этот скрипт? :-)
Есть и другие интересные геометрические фигуры:


not exp log srand xor s qq qx xor
s x x length uc ord and print chr
ord for qw q join use sub tied qx
xor eval xor print qq q q xor int
eval lc q m cos and print chr ord
for qw y abs ne open tied hex exp
ref y m xor scalar srand print qq
q q xor int eval lc qq y sqrt cos
and print chr ord for qw x printf
each return local x y or print qq
s s and eval q s undef or oct xor
time xor ref print chr int ord lc
foreach qw y hex alarm chdir kill
exec return y s gt sin sort split

Это знаменитый квадрат состоящий из ключевых слов PERL. Попробуем разобрать его подробнее. Первое, что бросается в глаза это повторяющиеся XOR и AND, которые, как известно, могут заменять;. Теперь можно рассмотреть вывод пробелов между словами: "print qq q q" "print qq q q" "print qq s s". qq говорит о том что последовательность ограниченная разделителем заключена в двойные кавычки. Разделителем тут являются символы q и s. Теперь код можно разделить на четыре части:

not exp log srand xor s qq qx xor
s x x length uc ord and print chr
ord for qw q join use sub tied qx
xor eval xor print qq q q xor

int
eval lc q m cos and print chr ord
for qw y abs ne open tied hex exp
ref y m xor scalar srand print qq
q q xor

int eval lc qq y sqrt cos
and print chr ord for qw x printf
each return local x y or print qq
s s and

eval q s undef or oct xor
time xor ref print chr int ord lc
foreach qw y hex alarm chdir kill
exec return y s gt sin sort split

Рассмотрим подробнее первую часть: not exp log srand XOR не выведет ничего на экран т.к. всегда будет ложь. s qq qx xor эквивалентно s// / Благодаря этой операции в переменной $_ окажется пробел. Следующая часть будет выглядеть так s/ /length uc ord and print chr ord for qw q join use sub tied q/ Эта операция заменит пробел в переменной $_ на length uc ord and print chr ord for qw q join use sub tied q. length uc ord and всегда истина, в расчет не берем. а вот print chr ord for qw q join use sub tied q как раз и напечатает слово «just». Это станет виднее, если преобразовать к следующему виду: print chr ord for('join','use','sub','tied'). Работает это так: for перебирает слова из массива, ord получает код только первого символа каждого слова, а chr обратная к ord функция, возвращает символ по коду. Затем eval выполнит содержимое переменной $_ (как раз и выведет just), а print qq q q выведет пробел. Оставшиеся части разбираются по тому же принципу.
Существуют japh'и в виде различных причудливых фигур:


Или от фанатов звездных войн :-)



[заключение]
Вообще разбор чужих japh'в хорошая тренировка, особенно для начинающих! Дерзайте! А по адресу http://www.cpan.org/misc/japh можно найти довольно большую коллекцию для опытов и тренировок ;-)
Теги:
Хабы:
Всего голосов 55: ↑38 и ↓17+21
Комментарии9

Публикации