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

    [введение]
    Практически любой программист, сталкивавшийся когда-либо с ВЕЛИКОМ ЯЗЫКОМ ПРОГРАММИРОВАНИЯ — 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 можно найти довольно большую коллекцию для опытов и тренировок ;-)

    Комментарии 9

      0
      мой первый пост! Прошу сильно не пинать, а указать на недочеты!
        0
        хабракат? :)
        0
        Ну и первый заслуженный плюс в карму =)
          0
          просто восхитительно! от этого в голове может вырасти интерпретатор перла
            0
            >Вообще разбор чужих japh'в хорошая тренировка, особенно для начинающих!
            Начинающим как раз не надо лезть пока туда. Либо каша в голове потом будет, либо начнут код такой писать в продакшн)) не хотелось бы наткнуться на поддержку такого кода))
            • НЛО прилетело и опубликовало эту надпись здесь
                +2
                Мне кажется, это уже было…
                  0
                  Конечно было. Это всё давно известные штуки. Только менее интересными они от этого не становятся. Каждый раз как их видишь, восхищаешься ими =) Разве не правда?
                  0
                  Да и смысл подобным заниматься? Не лучше ли в это время изучить что-нить новое.

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                  Самое читаемое