奇怪的perl代码 - 寻找解释

时间:2013-06-01 18:49:54

标签: perl obfuscation

我知道一点perl,但还不够深入了解下一个。

阅读perldelta 5.18我在5.18中找到了已经禁用的下一段代码。不计算这一点,仍然希望了解它是如何工作的。

这是代码,在评论中我理解

%_=(_,"Just another "); #initialize the %_ hash with key=>value   _ => 'Just another'
$_="Perl hacker,\n";    #assign to the $_ variable with "Perl..."
s//_}->{_/e;            # darkness. the /e - evauates the expression, but...
print

打印:

Just another Perl hacker,

我尝试了perl -MO=Deparse并获得了下一个

(%_) = ('_', 'Just another ');   #initializing the %_ hash
$_ = "Perl hacker,\n";           # as above
s//%{'_';}/e;                    # substitute to the beginning of the $_ - WHAT?
print $_;                        # print the result
japh syntax OK

奇怪的是什么(至少对我来说) - 运行“去掉的”代码并没有给出原始结果和打印:

1/8Perl hacker,

我会很高兴:

  1. 如果有人可以解释代码,特别是如果有人可以写一个帮助代码,(附加步骤)什么可以帮助我理解它是如何工作的 - 会发生什么。
  2. 解释,为什么解压缩的代码不会打印原始结果。
  3. 解除代码中的%{'_';}是什么意思?

1 个答案:

答案 0 :(得分:14)

替换运算符实际执行的代码可能实际上类似于

my $code = "do { $repl_expr }";

因此,当替换表达式为_}->{_时,将执行以下操作:

do { _}->{_ }

_只返回字符串_(因为严格关闭),所以与

相同
do { "_" }->{_}

相同
"_"->{_}

你所拥有的是散列元素取消引用,其中引用是符号引用(即字符串而不是实际引用)。通常禁止严格,这是工作中符号引用的一个例子:

%h1 = ( id => 123 );
%h2 = ( id => 456 );
print "h$_"->{id}, "\n"
   for 1..2;

这意味着

"_"->{_}    # Run-time symbol lookup

相同
$_{_}       # Compile-time symbol lookup

类似的技巧通常用于单行。

perl -nle'$c += $_; END { print $c }'

可以缩短为

perl -nle'$c += $_; }{ print $c'

因为使用-n时实际执行的代码是从等同于

的东西中获得的
my $code = "LINE: while (<>) { $program }";

%{'_';}

是一种非常奇怪的写作方式

%{'_'}

这是一个哈希解除引用。同样,这里的引用是一个符号引用。它相当于

%_

在标量上下文中,哈希值当前返回一个值,该值报告有关该哈希内部的一些信息(如果为空,则返回false值)。有人建议改变它以返回键的数量。