这是Perl meme “Just another Perl hacker”</a> 的变体。随着 JAPH 的发展,这个相对温和。
您需要做的第一件事是弄清楚如何解析 perl 程序。它在函数调用周围没有括号,+
并以有趣的方式使用类似引号的运算符。原来的程序是这样的:
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)))
请记住,一元加号是无操作的(除了强制标量上下文),所以现在应该看起来更熟悉了。这是对该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制作)。
''=~('(?{'.('-)@.)@_*([]@!@/)(@)@-@),@(@@+@)'
^'][)@]`}`]()`@.@]@%[`}%[@`@!#@%[').',"})')
不要在生产代码中使用任何这些。