此代码如何运作?
#!/usr/bin/perl
$i=4;$|=@f=map{("!"x$i++)."K$_^\x{0e}"}
"BQI!\\","BQI\\","BQI","BQ","B","";push
@f,reverse@f[1..5];@f=map{join"",undef,
map{chr(ord()-1)}split""}@f;{;$f=shift@
f;print$f;push@f,$f;select undef,undef,
undef,.25;redo;last;exit;print or die;}
答案 0 :(得分:16)
让我们首先通过perltidy
$i = 5;
$| = @f = map { ("!" x $i++) . "9$_*\x{0e}" } ">>>E!)", ">>>E)", ">>>E", ">>>", ">>", ">", "";
push @f, reverse @f[ 1..5 ];
@f = map {
join "",
map { chr(ord() - 1) }
split //
} @f;
{
$f = shift @f;
print $f;
push @f, $f;
select undef, undef, undef, .25;
redo;
last;
exit;
print or die;
}
第一行很明显。
第二行创建一个列表">>>E!)", ">>>E)", ">>>E", ">>>", ">>", ">", ""
,并将它们全部空格分开,并附加一个星号和一个'Shift Out'(回车后的字符)。
第三行将项目5到1(按此顺序)附加到该列表,因此它将是">>>E!)", ">>>E)", ">>>E", ">>>", ">>", ">", "", ">", ">>", ">>>", ">>>E"
。
地图将所有字符减1,从而创建8===D ()
等元素。
第二个循环只需每0.25秒循环打印一次循环中的元素。回车使它们相互覆盖,从而可以看到动画。最后几行永远不会到达,因此是虚假的。
答案 1 :(得分:14)
将文件中的数据加载到名为Perl解释器的程序中。解释器解析代码并将其转换为一系列“操作码” - 一种字节码语言,它位于Perl代码和代码运行的机器语言之间。如果转换过程中没有错误(称为“编译”),则代码由Perl解释器的另一部分执行。在执行期间,程序可能会更改机器的各种状态,例如分配,取消分配,读取和写入内存,或使用输入/输出和系统的其他功能。
(CW - 比我欢迎的更多铁杆黑客更正任何错误或误解并添加更多信息)
答案 2 :(得分:8)
这里没有魔法,只是混淆。让我们采取高层次的观点。首先要注意的是,稍后,字符串中的每个字符都被解释为它是前一个字符:
[1] map{chr(ord()-1)} ...
因此,像“6qD”这样的字符串将导致“5rC”(分别在'6','q'和'D'之前的字符)。主要的兴趣点是开头附近的字符串数组:
[2] ">>>E!)",">>>E)",">>>E",">>>",">>",">",""
这将我们稍后将替换的“掩码”序列定义为此字符串:
[3] "9$_*\x{0e}"
它们将被插入$_
点。字符串\x{0e}
表示十六进制控制字符;请注意\x{0d}
,就在它之前的字符,是一个回车。当我们做[1]时,这将被替换为[3]。
在汇编[3]字符串之前,我们在[2]中的每个元素前面加上等于i的!
个。每个连续元素比之前的元素多一个!
。请注意,其值在!
之前的字符是空格。
脚本的其余部分遍历每个汇编的数组元素,现在看起来更像是这样:
[4] "!!!!!9>>>E!)\x{0e}", ---> " 8===D ("
"!!!!!!9>>>E)\x{0e}", ---> " 8===D("
"!!!!!!!9>>>E\x{0e}", ---> " 8===D"
"!!!!!!!!9>>>\x{0e}", ---> " 8==="
"!!!!!!!!!9>>\x{0e}", ---> " 8=="
"!!!!!!!!!!9>\x{0e}", ---> " 8="
"!!!!!!!!!!!9\x{0e}", ---> " 8"
然后reverse
操作反向追加相同的元素,创建一个循环。
此时你应该能够看到产生动画的模式emerge。现在只需要动画完成动画中的每一步,然后再返回,这是由脚本的其余部分完成的。每个步骤的时间步长延迟由select语句控制:
[5] select undef, undef, undef, 0.25
告诉我们在每次迭代之间等待250毫秒。如果你想看到它加速或减速,你可以改变它。