简体   繁体   English

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

[英]is there a way to locally change the input record separator in perl?

Limiting the scope of a variable $x to a particular code chunk or subroutine, by means of my $x , saves a coder from a world of "global variable"-caused confusion.通过my $x将变量$x的范围限制为特定的代码块或子例程,可以将编码人员从“全局变量”引起的混乱世界中解救出来。

But when it comes to the input record separator, $/ , apparently its scope cannot be limited.但是当涉及到输入记录分隔符$/ ,显然它的范围不能被限制。 Am I correct in this?我在这方面正确吗?

As a consequence, if I forget to reset the input record separator at the end of a loop, or inside a subroutine, the code below my call to the subroutine can give unexpected results.因此,如果我忘记在循环结束时或在子例程内重置输入记录分隔符,则调用子例程下方的代码可能会产生意想不到的结果。 The following example demonstrates this.以下示例演示了这一点。

#!/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;
}

Here is how it behaves on an input file:以下是它在输入文件上的行为:

> 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.
> 

Note that if one tries to change to请注意,如果尝试更改为

my $/ = undef;

inside the subroutine, this generates an error.在子程序内部,这会产生错误。

Incidentally, among the stackoverflow tags, why is there no tag for "input record separator"?顺便说一句,在stackoverflow标签中,为什么没有“输入记录分隔符”的标签?

The answer for the my $/ = undef; my $/ = undef;的答案my $/ = undef; question is to change it to local $/ = undef;问题是将其更改为local $/ = undef; . . Then the revised code is as follows.那么修改后的代码如下。

#!/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;
}

Then there is no need to return the input record separator to another value, or to the default, $/ = "\\n";那么就不需要将输入记录分隔符返回另一个值,或者返回默认值, $/ = "\\n"; , by hand. , 用手。

You can use local to temporarily update the value of a global variable, including $/ .您可以使用local临时更新全局变量的值,包括$/

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

will use an undefined $/ as long as the look_through_other_file subroutine is in the call stack.只要look_through_other_file子例程在调用堆栈中,就会使用未定义的$/

You may encounter this construction in this common idiom, to slurp the entire contents of a file into a variable without altering the value of $/ for the rest of the program:你可能会在这个常见的习惯用法中遇到这种结构,将文件的全部内容放入一个变量中,而不改变程序其余部分的$/值:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM