当我使用文件句柄处理多行字符串时,如何避免使用Perl :: Critic警告?

时间:2009-10-09 15:19:16

标签: perl multiline filehandle perl-critic

有没有人能够解决一次处理多行字符串的任务,除了下面显示的字符串作为文件句柄解决方案?

my $multiline_string = "line one\nline two\nline three\nline four";
my $filehandle;
open( $filehandle, '<', \$multiline_string )
    or croak("Can't open multi-line string as a filehandle: $!");
while ( defined (my $single_line = <$filehandle>) ) {
    # do some processing of $single_line here ...
}
close( $filehandle );

我不想使用文件句柄的原因相当薄弱。 Test :: Perl ::当我在任何文件句柄上打开命令和close命令之间有超过10个源代码行时,批评者会发牢骚。我正在对$ single_line进行相当多的处理,所以在我的公开通话和近距离通话之间我实际上有大约40行代码,我认为没有办法将其降低到10。

我真的不想忽略我的构建中的Perl :: Critic测试,因为这实际上是一个不错的测试,每当我在我的代码中打开一个实际的磁盘文件时我想通过它。

8 个答案:

答案 0 :(得分:9)

让Perl Critic感到高兴,通过创建子程序并用文件的每一行调用它来让自己更开心。

use strict; use warnings;

sub do_something {
    my ($line) = @_;
    # do something with $line
}

open my $fh, '<', \$multiline_string
    or die "Cannot open scalar for reading: $!";

while(<$fh>) {
    chomp;
    do_something($_);
}

close $fh; 

答案 1 :(得分:5)

嗯,这不是让你有更小的代码块只能做一件事的呜咽的目的吗?制作一个子程序,完成每行所需的工作。

很多人都建议split /\n/split /^/更像是文件句柄方式。

答案 2 :(得分:3)

怎么样:

my $multiline_string = "line one\nline two\nline three\nline four";
my @lines = split(/\n/,$multiline_string);
foreach my $line (@lines) {
    #do stuff with string
}

答案 3 :(得分:3)

我可能会遗漏一些东西,但你可以这样做:

my @lines = split(/\n/,$multiline_string);
foreach my $single_line (@lines) {
  ...
}

答案 4 :(得分:3)

很久以前,我甚至不知道你可以将多行字符串变成文件句柄,但有split

foreach my $single_line (split /\n/, $multiline_string) {
    # process $single_line here
    # although note that it doesn't end in a newline anymore
}

在此处插入关于使用文字和非便携式\n的免责声明。

答案 5 :(得分:2)

Perl::Critic很不错,但是当你开始着迷它的一些仲裁要求时,它开始浪费你的时间而不是保存它。我只是让文件句柄超出范围而不用担心关闭:

 my $multiline_string = "line one\nline two\nline three\nline four";

 {
     open my( $fh ), '<', \$multiline_string )
         or croak("Can't open multi-line string as a filehandle: $!");
     while ( defined (my $single_line = <$fh>) ) {
         # do some processing of $single_line here ...
     }
 }

很多人都会接受正规用途或分裂,但我认为这很邋..您无需创建新列表并在程序中耗尽更多内存。

答案 6 :(得分:0)

你可以使用正则表达式。

#!/usr/bin/perl

use strict;
use warnings;

my $s = "line one\nline two\nline three\nline four";

while ($s =~ m'^(.*)$'gm) {
    print "'$1'\n";
}

die "Exited loop too early\n" unless pos $s == length $s;

或者您可以使用split

for my $line ( split m'\n', $multiline_string ){

  # ...

}

答案 7 :(得分:-1)

我个人喜欢使用$/分隔多行字符串中的行。

my $multiline_string = "line one\nline two\nline three\nline four";
foreach (split($/, $mutliline_string)) {
  process_file($_);
}
sub process_file {
  my $filename = shift;
  my $filehandle;
  open( $filehandle, '<', $filename )
      or croak("Can't open multi-line string as a filehandle: $!");
  while ( defined (my $single_line = <$filehandle>) ) {
      process_line($single_line);
  }
  close( $filehandle );
}
sub process_line {
  my $line = shift;
  ...
}