$ /和本地$ /的区别

时间:2019-04-01 07:04:34

标签: perl variables global-variables temp

对于我的程序,我需要使用FASTA文件并对其进行一些计算。为了做到这一点,我使用了local $/ = "^>,将文件切成标题行和序列行。尽管我的程序可以执行我想要的操作,但为什么我不能仅仅使用$/ = "^>"?当我尝试它时,我的结果不是我所需要的,我很感兴趣为什么会这样。这是我的简化代码:

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

3 个答案:

答案 0 :(得分:5)

local

  

将列出的变量修改为封闭块,文件或eval的本地变量。

它保存了(已经存在的)变量的值,可以根据需要对其进行更改,并且一旦退出范围,仍将恢复其原始值。

正因为如此,它正好与@item() 之类的全局变量一起使用-通过$/的大小化它们,我们可以在需要的范围内更改其值,而无需整体更改程序。

提供了更多in perlsub

显示的内容虽然引起了疑问。 $/ variable使用字符串,而不是正则表达式;我记得那些“ fasta”文件的行以local开头,而不是以>开头。另外,^>需要在读取行之前设置(使用$/),但我看不出所显示的代码如何实现其意图。

答案 1 :(得分:5)

local $var保存$var的值,并向堆栈中添加一个指令,当退出范围时(即使是例外),该指令将导致$var的值恢复。这是最接近my的东西,可用于打包变量。

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

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

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

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


  

为什么我不能简单地使用$/ = "^>"

然后,更改不会在块末尾撤消,因此它将影响<>条件下的while以及执行读取的循环后的所有代码。 / p>


我如何处理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;
   }
}

答案 2 :(得分:1)

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

  

请记住:$/的值是一个字符串,而不是正则表达式。 awk 必须在某些方面做得更好。 :-)

  • 您可以修改$/while (<>)的值,而该值应该会受到影响。

正确的是:

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

然后观察到的差异就消失了,即无论有没有local,代码的行为都相同。

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