`$/` 和 `local $/` 的区别

The difference between `$/` and `local $/`

对于我的程序,我需要使用 FASTA 文件并用它们做一些计算。为了做到这一点,我使用 local $/ = "^>,将我的文件压缩成 header 行和序列行。虽然我的程序做我想做的事,但为什么我不能简单地使用 $/ = "^>"?当我尝试时,我的结果不是我需要的,我很想知道为什么会这样。这是我的简化代码:

my @array;
while(<>){
    local $/ = "^>";
    chomp;
    push (@array, $_);
    if(eof){
        for(@array){
            ...
        }
    ...
    }
    if(eof){
        @array = ();
    }

local

modifies the listed variables to be local to the enclosing block, file, or eval.

它保存了一个(已经存在的)变量的值,然后可以根据需要更改它,并且一旦退出范围,它的原始值就会恢复。

因此,它精确地与 $/ 这样的全局变量一起使用——通过 local-izing 它们,我们可以在我们需要的范围内改变它们的值,而不是让它改变整个程序。

提供更多 in perlsub

虽然显示的内容引发了问题。 $/ variable 接受一个字符串,而不是正则表达式;根据我的记忆,那些 "fasta" 文件的行以 > 开头,而不是 ^>。此外,$/ 需要在读取行之前设置(使用 <>),我看不到显示的代码如何实现其意图。

local $var 保存 $var 的值,并向堆栈添加一个指令,该指令将导致 $var 的值在范围退出时恢复(即使是异常).它是最接近 my 的可用于封装变量的东西。

$_ = 123;
{
   local $_ = 456;
   # $_ is 456 here.
}
# $_ is back to being 123 here.

这有助于避免在周围代码或调用者(在 subs 的情况下)中引起问题。

请注意,$/ 的值是逐字符匹配的。它不被视为正则表达式。

请注意,$/ 似乎在您发布的代码中无缘无故地设置了(除非您遗漏了某些内容)。


why can't I just simply use $/ = "^>"

然后,更改不会在块的末尾撤消,因此它会影响 while 条件中的 <> 以及执行读取的循环之后的任何代码.


我如何处理 FASTA 文件:

my ($header, $seq);
while (1) {
   my $line = <>;
   if (!defined($line) || $line =~ /^>/) {
      work($header, $seq) if defined($header);

      last if !defined($line);

      chomp($line);
      $header = substr($line, 1);
      $seq = "";
   } else {
      chomp($line);
      $seq .= $line;
   }
}

您的代码依赖于未定义的行为:

Remember: the value of $/ is a string, not a regex. awk has to be better for something. :-)

  • 你修改 $/ 里面 的值 while (<>) 应该会影响它。

正确的是:

my @array;
{
    local $/ = ">";
    while (<>) {
        ...
    }
}

然后观察到的差异就消失了,即代码在有或没有 local 的情况下表现相同。

但是您应该始终对全局变量使用 local 以确保在离开 local 定义的范围时恢复原始值。