Пояснение к 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
в результате чего получается копия собственного исходного кода.