有没有办法在perl中本地更改输入记录分隔符



通过my $x将变量$x的范围限制为特定的代码块或子例程,可以从";全局变量"-造成混乱。

但是,当涉及到输入记录分隔符$/时,显然其范围不能受到限制。我说的对吗?

因此,如果我忘记在循环结束时或在子例程内重置输入记录分隔符,则我对该子例程的调用下方的代码可能会产生意外结果。下面的示例演示了这一点。

#!/usr/bin/perl
use strict; use warnings;
my $count_records; my $infile = $ARGV[0]; my $HANDLEinfile;
open $HANDLEinfile, '<', $infile or die "cannot open $infile for reading";
$count_records = 0;
while(<$HANDLEinfile>)
{
$count_records++; 
print "$count_records:n";
print;
}
close $HANDLEinfile;
look_through_other_file();
print "nNOW, after invoking look_through_other_file:n";
open $HANDLEinfile, '<', $infile or die "cannot open $infile for reading";
$count_records = 0;
while(<$HANDLEinfile>)
{
$count_records++; 
print "$count_records:n";
print;
}
close $HANDLEinfile;
sub look_through_other_file
{
$/ = undef;
# here, look through some other file with a while loop
return;
}

以下是它在输入文件上的行为:

> z.pl junk
1:
All work
2:
and
3:
no play
4:
makes Jack a dull boy.
NOW, after invoking look_through_other_file:
1:
All work
and
no play
makes Jack a dull boy.
> 

请注意,如果试图更改为

my $/ = undef;

在子程序中,这会生成一个错误。

顺便说一句,在stackoverflow标签中,为什么没有"的标签;输入记录分隔符";?

my $/ = undef;问题的答案是将其更改为local $/ = undef;。修订后的代码如下。

#!/usr/bin/perl
use strict; use warnings;
my $count_records; my $infile = $ARGV[0]; my $HANDLEinfile;
open $HANDLEinfile, '<', $infile or die "cannot open $infile for reading";
$count_records = 0;
while(<$HANDLEinfile>)
{
$count_records++; 
print "$count_records:n";
print;
}
close $HANDLEinfile;
look_through_other_file();
print "nNOW, after invoking look_through_other_file:n";
open $HANDLEinfile, '<', $infile or die "cannot open $infile for reading";
$count_records = 0;
while(<$HANDLEinfile>)
{
$count_records++; 
print "$count_records:n";
print;
}
close $HANDLEinfile;
sub look_through_other_file
{
local $/ = undef;
# here, look through some other file with a while loop
return;
}

这样就不需要手动将输入记录分隔符返回到另一个值或默认值$/ = "n";

您可以使用local临时更新全局变量的值,包括$/

sub look_through_other_file {
local $/ = undef;
# here, look through some other file with a while loop
return;
}

只要CCD_ 10子程序在调用堆栈中,就会使用未定义的CCD_。

在这个常见的习惯用法中,您可能会遇到这样的构造,即在不更改程序其余部分的$/值的情况下,将文件的全部内容拖入变量:

open my $fh, "<", "/some/file";
my $o = do { local $/; <$fh> };

最新更新