一些Perl的细微之处

Dav*_*man 2 perl

我已经在Perl中编程了一段时间,但我从未理解过Perl的一些细微之处:

$ _变量的使用和设置/取消设置让我感到困惑.例如,为什么呢

# ...
shift @queue;
($item1, @rest) = split /,/;
Run Code Online (Sandbox Code Playgroud)

工作,但(至少对我而言)

# ...
shift @queue;
/some_pattern.*/ or die();
Run Code Online (Sandbox Code Playgroud)

似乎不起作用?

另外,我不明白使用foreach与文件迭代文件之间的区别while.例如,我似乎得到了不同的结果

while(<SOME_FILE>){  
    # Do something involving $_        
}
Run Code Online (Sandbox Code Playgroud)

foreach (<SOME_FILE>){
    # Do something involving $_
}
Run Code Online (Sandbox Code Playgroud)

谁能解释这些微妙的差异?

Sin*_*nür 13

shift @queue;
($item1, @rest) = split /,/;
Run Code Online (Sandbox Code Playgroud)

如果我理解正确的话,你似乎认为这会将元素转移@queue$_.事实并非如此.

移出的值@queue只是消失了以下split操作包含在$_其中的任何内容(独立于shift调用).

while(<SOME_FILE>){  
    # Do something involving $_        
}
Run Code Online (Sandbox Code Playgroud)

while语句中的文件句柄中读取是特殊的:它相当于

while ( defined( $_ = readline *SOME_FILE ) ) {
Run Code Online (Sandbox Code Playgroud)

这样,您可以逐行处理甚至是巨大的文件.

另一方面,

for(<SOME_FILE>){  
    # Do something involving $_        
}
Run Code Online (Sandbox Code Playgroud)

将首先将整个文件作为行列表加载到内存中.尝试1GB文件,看看差异.

  • 我想补充一点,为了知道何时隐式使用`$ _`,你必须RTFM. (3认同)
  • 我想补充一点,明确地命名$ _将帮助下一个极其想读代码的人. (2认同)

Mic*_*ebs 5

另一个虽然微妙的区别:

while (<FILE>) {
}
Run Code Online (Sandbox Code Playgroud)

和:

foreach (<FILE>) {
}
Run Code Online (Sandbox Code Playgroud)

是while()将修改其范围之外的$ _的值,而foreach()使$ _ local.例如,以下将死:

$_ = "test";
while (<FILE1>) {
    print "$_";
}
die if $_ ne "test";
Run Code Online (Sandbox Code Playgroud)

然而,这不会:

$_ = "test";
foreach (<FILE1>) {
    print "$_";
}
die if $_ ne "test";
Run Code Online (Sandbox Code Playgroud)

对于更复杂的脚本,这变得更加重要.想象一下:

sub func1() {
    while (<$fh2>) {  # clobbers $_ set from <$fh1> below
        <...>
    }
}

while (<$fh1>) {
    func1();
    <...>
}
Run Code Online (Sandbox Code Playgroud)

就个人而言,由于这个原因,我不会使用$ _,除了它的可读性较差等.