对于我的程序,我需要使用FASTA文件并对其进行一些计算。为了做到这一点,我使用了local $/ = "^>
,将文件切成标题行和序列行。尽管我的程序可以执行我想要的操作,但为什么我不能仅仅使用$/ = "^>"
?当我尝试它时,我的结果不是我所需要的,我很感兴趣为什么会这样。这是我的简化代码:
my @array;
while(<>){
local $/ = "^>";
chomp;
push (@array, $_);
if(eof){
for(@array){
...
}
...
}
if(eof){
@array = ();
}
答案 0 :(得分:5)
将列出的变量修改为封闭块,文件或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
定义的范围时恢复原始值。