这实际上是一个相当简单的 JAPH。它的两个最大特点是分割构成“图像”大部分的数据字符串,以及半递归打印。
这是我清理格式时得到的代码
my ($j,$a,$p,$h);
$j = sub {
print( chr( $p += $a->[$h++] ) );
$j
};
;;
$a = [0, split "[: \n]+", # the split regex
q/43 -002:1 # input string start: q/ ...
-084 065:13
0001 000005
-0012 -00003
000013 -82 00048
21:13:-6.00:-76:72
-007.:02:00008.00
:::-6.00:::013
-70:3::-70:.64
/]; # input string end: .../
# print Dumper $a; # <--- this is my line
$p = 0x4a;;
$h=0;
$j->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->();
第一部分是 4 个主要变量的声明和赋值:
$j
$j
是打印字符的代码引用,然后返回对自身的引用。打印包括几个步骤:
$a->[$h++]
遍历@$a
数组,返回一个元素
$p += ...
该元素被添加到$p
print chr( $p ... )
然后$p
返回 chr() 并打印结果字符。
sub 块中的最后一个是$j
,这意味着每次迭代,sub 的返回值将是对自身的引用。这是允许半递归功能的部分。
$一个
$a
是对包含 0 和输入字符串拆分结果的数组的引用。一行代码中还发生了一些事情:
q/43 .../
这是带有分隔符斜杠的常规q()
单引号字符串/
。]
它在表示数组引用的右括号之前结束。
split "[: \n]+",
这是对字符类的拆分,重复 1 次或多次。它里面有额外的空间(我在这里删除了)来填充 JAPH 本身的空间。基本上这会删除所有冒号、空格和换行符并返回结果列表。
$a = [0, ... ]
拆分的列表被添加到0
(只有一个元素)的列表中,并且所有内容都用括号括起来以表示数组引用,然后将其存储在$a
.
我假设列表开头是0
因为代码有一个一次性错误,因为它$p
的原始值是输出中的第一个字母。
这是的Data::Dumper
输出$a
:
$VAR1 = [
0,
'43',
'-002',
'1',
'-084',
'065',
'13',
'0001',
'000005',
'-0012',
'-00003',
'000013',
'-82',
'00048',
'21',
'13',
'-6.00',
'-76',
'72',
'-007.',
'02',
'00008.00',
'-6.00',
'013',
'-70',
'3',
'-70',
'.64'
];
$p 和 $h
$p
和$h
只是数字,它们在其中的作用分别是函数的源编号和数组的chr()
迭代器。@$a
最后一行是$j
运行子程序并打印 JAPH 的部分。链式->()
语法意味着每次前一次迭代的返回值用于下一次执行。并$j
返回对自身的引用,这使其成为半递归事务,只有值发生变化。
我想这类似于这样做:
$x = $j->();
$y = $x->();
$z = $y->();
...
所以让我们来看看前几个步骤
$j->()
执行
$a->[$h++]
$h
递增到 1,将 0 返回到$a
子带,该子带返回 的第一个元素$a
,即0
.
$p += 0
这0
被添加到$p
,并将 (74) 的值返回$p
给 chr
print chr(74)
这现在打印J
到标准输出
$j
被退回。
->()
对返回值执行另一次执行,因此$j
再次运行。
$a->[$h++]
$h
递增到 2,返回 1$a
返回第二个元素,即43
.
$p += 43
74 + 43 = 117 返回chr
print chr(117)
这打印u
的元素$a
既有正面的也有负面的,将数字移动到需要的位置。最后,所有的字母都打印出来了:Just another Perl hacker,
以下是 10 次首次处决的概要:
p => 74 += 0 = 74 output => chr( 74) J
p => 74 += 43 = 117 output => chr(117) u
p => 117 += -002 = 115 output => chr(115) s
p => 115 += 1 = 116 output => chr(116) t
p => 116 += -084 = 32 output => chr( 32)
p => 32 += 065 = 97 output => chr( 97) a
p => 97 += 13 = 110 output => chr(110) n
p => 110 += 0001 = 111 output => chr(111) o
p => 111 += 000005 = 116 output => chr(116) t
p => 116 += -0012 = 104 output => chr(104) h