无法理解 Perl 中的简短算法

use*_*872 3 algorithm perl file

我从未使用过 Perl,这就是为什么我需要一点帮助才能理解以下代码:

for ($i=0; $i<@ARGV; $i++) {
    open F, $ARGV[$i];
    while (<F>) {
        chomp;
        ($y,@x) = split;
        print $y;
        map { print " *$_ $i$_" } @x;
        print "\n";
    }
}
Run Code Online (Sandbox Code Playgroud)

我看到它遍历一个文件(每行?),然后while(<F>),意味着不为空?chomp 从换行符、空格等中去除字符串。

perl 的一般概念让我感到困惑,谁能向我解释这个例子?

Sob*_*que 5

while特别是发生了什么- 并且需要更多解释。

Perl 有一个隐式变量的概念$_——这个变量被设置为每个循环结构中的当前事物forwhile

当您为while循环执行此操作时,您实际得到的是:

while ( defined $_ = <$FH> ) {
Run Code Online (Sandbox Code Playgroud)

这意味着它从文件句柄中读取一行,并测试操作的结果。如果您点击 EOF,则 while 循环结束。

但是,通过循环,你有机会获得$_-无一不chompsplit默认行为在此。

所以你在做:

 while ( defined $_ = <$FH> ) { 
     chomp ( $_ ); #strip trailing whitespace;
     ( $x, @y ) = split ( ' ', $_ ); 
Run Code Online (Sandbox Code Playgroud)

此时发生的事情是您将一个列表分配给另一个列表。因此,'split' 生成的列表被分配 - 按顺序( $x, @y )- 制作$x第一个元素,以及@y其他所有元素。

那条map线被滥用了map- 因此它有点令人困惑并不太令人惊讶。

什么map应该做的是应用转换到一个列表和输出另一个列表。

所以你可能会这样做:

my @uppercase = map { uc } @list_of_lowercase; 
Run Code Online (Sandbox Code Playgroud)

小写的列表变成了大写的列表,因为该uc函数在每个元素上运行。

但是,通过不分配输出,这是一个很大的警告信号,表明他们真正应该使用的是 for

print "$y ";
foreach my $value ( @x ) {
   print "*$value $i$value";
}
print "\n"; 
Run Code Online (Sandbox Code Playgroud)

(我倾向于在命名事物时使用foreach而不是for命名,但它们实际上是相同的)。