`$/` 和 `local $/` 的区别
The difference between `$/` and `local $/`
对于我的程序,我需要使用 FASTA 文件并用它们做一些计算。为了做到这一点,我使用 local $/ = "^>
,将我的文件压缩成 header 行和序列行。虽然我的程序做我想做的事,但为什么我不能简单地使用 $/ = "^>"
?当我尝试时,我的结果不是我需要的,我很想知道为什么会这样。这是我的简化代码:
my @array;
while(<>){
local $/ = "^>";
chomp;
push (@array, $_);
if(eof){
for(@array){
...
}
...
}
if(eof){
@array = ();
}
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;
}
}
您的代码依赖于未定义的行为:
- 引用自perlvar
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
定义的范围时恢复原始值。
对于我的程序,我需要使用 FASTA 文件并用它们做一些计算。为了做到这一点,我使用 local $/ = "^>
,将我的文件压缩成 header 行和序列行。虽然我的程序做我想做的事,但为什么我不能简单地使用 $/ = "^>"
?当我尝试时,我的结果不是我需要的,我很想知道为什么会这样。这是我的简化代码:
my @array;
while(<>){
local $/ = "^>";
chomp;
push (@array, $_);
if(eof){
for(@array){
...
}
...
}
if(eof){
@array = ();
}
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;
}
}
您的代码依赖于未定义的行为:
- 引用自perlvar
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
定义的范围时恢复原始值。