Объяснение perl quine

Я нашел этот квайн недавно

$a='$a=%c%s%c;printf($a,39,$a,39,10);%c';printf($a,39,$a,39,10);

И я просто не могу прийти в себя. Я не нашел объяснений в google/SO для этого конкретного, поэтому я надеюсь, что кто-нибудь объяснит мне, как это работает :-)


person Vince    schedule 10.10.2013    source источник


Ответы (2)


Посмотрите printf параметры и подставьте их вручную,

(39 — одинарная кавычка, ' и 10 — новая строка \n при интерпретации как %c), поэтому $a начинаются как

$a=%c%s%c;printf($a,39,$a,39,10);%c

становится (заменены символы, отмеченные ниже, на ^)

$a='%s%c;printf($a,39,$a,39,10);%c
   ^ (first %c replaced)
$a='$a=%c%s%c;printf($a,39,$a,39,10);%c%c;printf($a,39,$a,39,10);%c
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ (%s replaced)
$a='$a=%c%s%c;printf($a,39,$a,39,10);%c';printf($a,39,$a,39,10);%c
                                       ^ (second %c replaced)

и наконец

$a='$a=%c%s%c;printf($a,39,$a,39,10);%c';printf($a,39,$a,39,10);\n
                                             (last %c replaced) ^^ 
person mpapec    schedule 10.10.2013

Этот код состоит из двух строк.

Назначение переменной:

$a='$a=%c%s%c;printf($a,39,$a,39,10);%c';

И printf:

printf($a,39,$a,39,10)

Прежде всего, давайте узнаем кое-что о printf. Если вы посмотрите документацию sprintf, вы увидите, что printf('%c',39) напечатает 39-й символ, который равен ', а printf('%c',10) новая строка \n. Еще одна вещь, о которой следует помнить, это то, что printf принимает список параметров, что означает, что printf('%s%s','foo','bar') напечатает foobar.

Итак, теперь должно быть ясно, что printf($a,39,$a,39,10) берет формат из $a и выполняет следующие 4 преобразования (равные количеству знаков % в строке $a)

  • использует 2-й аргумент 39 для 1-го вхождения %c (проверьте переменную $a),
  • затем он использует строку $a для %s
  • 4-й аргумент 39 из printf для следующего %c
  • и, наконец, 10 для последнего %c

что приводит к копии собственного исходного кода.

person psxls    schedule 10.10.2013