对于我的程序,我需要使用 FASTA 文件并用它们进行一些计算。为了做到这一点,我使用 local $/ = "^>
,将我的文件切成标题行和序列行。虽然我的程序做了我想让它做的事情,但为什么我不能简单地使用$/ = "^>"
?当我尝试它时,我的结果不是我需要的,我很感兴趣为什么会这样。这是我的简化代码:
my @array;
while(<>){
local $/ = "^>";
chomp;
push (@array, $_);
if(eof){
for(@array){
...
}
...
}
if(eof){
@array = ();
}
local $var
保存 $var
的值,并向堆栈添加一个指令,该指令将导致在退出作用域时恢复$var
的值(即使异常(。这是最接近my
可用于包变量的东西。
$_ = 123;
{
local $_ = 456;
# $_ is 456 here.
}
# $_ is back to being 123 here.
这对于避免在周围的代码或调用方(在 subs 的情况下(中引起问题很有用。
请注意,$/
的值是逐个字符匹配的。它不被视为正则表达式。
请注意,在您发布的代码中,$/
似乎无缘无故地设置(除非您遗漏了一些内容(。
为什么我不能简单地使用
$/ = "^>"
然后,更改不会在块结束时撤消,因此它会影响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;
}
}
本地
将列出的变量修改为封闭块、文件或 EVAL 的局部变量。
它保存了一个(已经存在的(变量的值,然后可以根据需要进行更改,并且在退出范围后仍会恢复其原始值。
因此,它与全局变量(如$/
(精确地一起使用 - 通过local
-size 它们,我们可以在我们需要的范围内更改它们的值,而不会在整个程序中更改它们的值。
Perlsub中提供了更多内容。
不过,显示的内容提出了问题。$/
变量采用字符串,而不是正则表达式;据我所知,那些"fasta"文件的行以 >
开头,而不是以 ^>
开头。此外,$/
需要在读取行(带 <>
(之前进行设置,并且我看不到显示的代码如何实现其意图。
您的代码依赖于未定义的行为:
- 引用佩尔瓦的话
请记住:
$/
的值是一个字符串,而不是正则表达式。awk必须做得更好。:-)
- 您可以在
while (<>)
内修改$/
的值,这应该会影响它。
正确的是:
my @array;
{
local $/ = ">";
while (<>) {
...
}
}
然后观察到的差异就会消失,即代码在有或没有local
的情况下表现相同。
但是,应始终对全局变量使用 local
,以确保在离开local
定义范围时恢复原始值。