【问题标题】:The difference between `$/` and `local $/``$/` 和 `local $/` 的区别
【发布时间】:2019-04-01 07:04:34
【问题描述】:

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

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

【问题讨论】:

  • perlvar: "记住:$/ 的值是一个字符串,而不是一个正则表达式。awk 必须更好一些。:-)"

标签: perl variables global-variables temp


【解决方案1】:

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

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

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

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

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


为什么我不能直接使用$/ = "^&gt;"

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


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

【讨论】:

  • 谢谢,您的回答真的很有帮助。我忽略了所有的计算,但它们是我设置 $/ 的原因。
  • $/ 仅由readline(又名&lt;&gt;&lt;FH&gt;&lt;$fh&gt;)使用,不用于计算。
  • 是的,我明白了。但要进行这些计算,我需要处理我的文件才能进行这些计算
  • 我已经对我的答案做了补充。
【解决方案2】:

local

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

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

因此,它与$/ 之类的全局变量精确配合使用——通过local 对它们进行化处理,我们可以在需要的范围内更改它们的值,而不需要在整个程序中更改它们。

提供更多in perlsub

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

【讨论】:

    【解决方案3】:

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

    记住:$/ 的值是一个字符串,而不是一个正则表达式。 awk 必须更好。 :-)

    • 你修改$/的值while (&lt;&gt;)应该会影响它。

    正确的是:

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

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

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

    【讨论】:

    • 没有未定义的行为被调用。
    • local $/ = "\n&gt;"; 会更符合本意
    猜你喜欢
    • 1970-01-01
    • 2012-07-25
    • 1970-01-01
    • 2019-05-11
    • 2019-05-23
    • 2011-01-28
    • 2012-08-08
    • 2010-09-12
    • 1970-01-01
    相关资源
    最近更新 更多