Пояснение к Perl Quine

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

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

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

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) ^^ 

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

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

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

И принтф:

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

в результате чего получается копия собственного исходного кода.

Другие вопросы по тегам