Хитрый Perl-квайн

Автор: admin от 5-04-2019, 18:05, посмотрело: 108

Прим. пер.: Встретил сегодня в твиттере очень забавный, на первый взгляд, тред. А потом пригляделся и понял, что он не только забавный, но и занятный. А раз уж так сложилось, что сегодня пятница, то решил, что стоит поделиться обнаруженным и с товарищами:)



Хитрый Perl-квайн



Сохраните следующую программу в /tmp/quine.pl



Illegal division by zero at /tmp/quine.pl line 1.


Запустите её командой
perl /tmp/quine.pl
и она выведет свой собственный код.



«Квайны-обманки» довольно просто сочинять на многих языках программирования, где ошибка синтаксиса в исходнике провоцирует парсер на вывод ошибки, которая бы совпадала с исходным текстом программы. Я опубликовал несколько подобных «обманок» у себя в Twitter, включая следующую:



  File "quine.py", line 1
    File "quine.py", line 1
   ^
Indentationerror: unexpected indent


Но перловый квайн в начале этой заметки — это обманка совершенно другого рода — программа разбирается корректно.непрямым синтаксисом объекта", который выглядит следующим образом:



метод объект аргументы

чаще всего можно видеть как



print $filehandle "message";
my $instance = new Class(args);


хотя для Perl более предпочтителен следующий синтаксис:



$filehandleprint("message");
my $instance = Classnew(args);


В документации perlobj говорится:



Для разбора этого кода Perl использует эвристики, основанные на том, какие имена пакетов ему известны, какие в текущем пакете существуют подпрограммы, какие слова он до этого встречал и анализируя другие вводные данные. Излишне говорить, что эвристика может давать очень неожиданные результаты!




Как он разбирает этот код?

Начиная с правой стороны,



pl line 1.


разбирается как вызов метода



linepl(1.)


где line — это имя пакета (класса), а pl — это метод.



В середине «at», «tmp» и «quine» разбираются как простые слова, т.е. строки. Выражение разбирается следующим образом:



(("at" / "tmp") / "quine") . linepl(1.)


Слева находятся два сложенных непрямых вызова метода,



divisionIllegal(zeroby( ... ))


внутреннее выражение, выполняющееся первым, это:



"at" / "tmp"


И это мгновенно вызывает исключение деления на ноль.

Источник: Хабр / Интересные публикации

Категория: Программирование

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

Добавление комментария

Имя:*
E-Mail:
Комментарий:
Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
Введите два слова, показанных на изображении: *