Ответ 1
Это вариант на "Просто еще один хакер Perl" , Perl meme. Как JAPHs идут, это одно относительно ручное.
Первое, что вам нужно сделать, это выяснить, как разбирать программу perl. В нем отсутствуют круглые скобки вокруг вызовов функций и интересными способами используются операторы +
и quote-like. Исходная программа такова:
print+pack+q,c*,,map$.+=$_,74,43,-2,1,-84, 65,13,1,5,-12,-3, 13,-82,44,21, 18,1,-70,56, 7,-77,72,-7,2, 8,-6,13,-70,-34
pack
является функцией, тогда как print
и map
являются операторами списка. В любом случае, имя функции или не нулевого оператора, за которым следует знак плюс, не может использовать +
в качестве двоичного оператора, поэтому оба знака +
в начале унарные операторы. Эта странность описана в руководстве .
Если мы добавим круглые скобки, используйте синтаксис блока для map
и добавьте немного пробелов, получим:
print(+pack(+q,c*,,
map{$.+=$_} (74,43,-2,1,-84, 65,13,1,5,-12,-3, 13,-82,44,21,
18,1,-70,56, 7,-77,72,-7,2, 8,-6,13,-70,-34)))
Следующий сложный бит - это q
здесь q
котировочный оператор. Это чаще всего записывается с одинарными кавычками:
print(+pack(+'c*',
map{$.+=$_} (74,43,-2,1,-84, 65,13,1,5,-12,-3, 13,-82,44,21,
18,1,-70,56, 7,-77,72,-7,2, 8,-6,13,-70,-34)))
Помните, что унарный плюс - это не-op (кроме форсирования скалярного контекста), поэтому теперь все должно выглядеть более знакомым. Это вызов функции pack
с форматом c*
, что означает "любое количество символов, указанное их номером в текущем наборе символов", Альтернативный способ написать это
print(join("", map {chr($.+=$_)} (74, …, -34)))
Функция map
применяет поставляемый блок к элементам списка аргументов по порядку. Для каждого элемента $_
устанавливается значение элемента, а результат вызова map
- это список значений, возвращаемых при выполнении блока на последующих элементах. Более длинный способ написать эту программу будет
@list_accumulator = ();
for $n in (74, …, -34) {
$. += $n;
push @list_accumulator, chr($.)
}
print(join("", @list_accumulator))
Переменная $.
содержит общее количество чисел. Цифры выбраны так, что общее количество - это коды ASCII символов, которые автор хочет напечатать: 74 = J
, 74 + 43 = 117 = u
, 74 + 43-2 = 115 = s
, и т.д. Они отрицательные или положительные в зависимости от того, каждый ли символ до или после предыдущего в порядке ASCII.
Для вашей следующей задачи объясните этот JAPH (созданный EyesDrop).
''=~('(?{'.('-)@.)@_*([]@[email protected]/)(@)@[email protected]),@(@@[email protected])'
^'][)@]`}`]()`@[email protected]]@%[`}%[@`@!#@%[').',"})')
Не используйте это в производственном коде.