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

发布于 2024-08-06 18:24:35 字数 676 浏览 8 评论 0原文

除了下面所示的字符串作为文件句柄解决方案之外,是否有人有解决方案来一次处理一行一行的多行字符串?

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 );

我不想使用文件句柄的原因很弱。当我在任何文件句柄上的打开命令和关闭命令之间有超过 10 行源代码行时,Test::Perl::Critic 就会发牢骚。我正在对 $single_line 进行相当多的处理,所以我实际上在 open call 和 close call 之间有大约 40 行代码,而且我没有看到任何方法可以将其减少到 10 行。

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

Does anyone have a solution to the task of processing a multi-line string one line at a time, other than the string-as-a-filehandle solution shown below?

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 );

My reason for not wanting to use a filehandle is pretty weak. Test::Perl::Critic whines when I have more than 10 source lines between my open command and my close command on any filehandle. I'm doing quite a bit of processing of $single_line so I actually have about 40 lines of code between my open call and my close call and I don't see any way to bring that down to 10.

And I don't really want to ignore the Perl::Critic test in my build because that's actually a decent test that I'd like to pass whenever I'm opening an actual disk file in my code.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

私藏温柔 2024-08-13 18:24:35

通过创建子例程并在文件的每一行中调用它,可以让 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; 

Make the Perl Critic happy, and make yourself even happier, by creating a subroutine, and calling it with each line of the file.

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; 
一口甜 2024-08-13 18:24:35

嗯,抱怨的目的不就是让你拥有只做一件事的更小的代码块吗?创建一个子例程来执行每行所需的操作。

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

Um, isn't the purpose of the whine to get you to have smaller blocks of code that do just one thing? make a subroutine that does what's needed for each line.

Many people have suggested split /\n/. split /^/ is more like the filehandle way.

苦妄 2024-08-13 18:24:35

怎么样:

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
}

What about:

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
}
最好是你 2024-08-13 18:24:35

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

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

I might be missing something, but could you do:

my @lines = split(/\n/,$multiline_string);
foreach my $single_line (@lines) {
  ...
}
澉约 2024-08-13 18:24:35

早在我知道可以将多行字符串硬塞到文件句柄中之前,就已经存在 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 的免责声明。

Long before I even knew you could shoehorn a multiline string into a filehandle, there was split:

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

Insert disclaimer about using literal and non-portable \n here.

赏烟花じ飞满天 2024-08-13 18:24:35

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

很多人使用正则表达式或拆分,但我认为这是草率的。您不需要创建新列表并在程序中使用更多内存。

Perl::Critic is nice, but when you start obsessing about some of its arbitary requirements, it starts to waste your time rather than save it. I just let the filehandle go out of scope and don't worry about the close:

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

A lot of people reach for regexes or split, but I think that's sloppy. You don't need to create a new list and use up a lot more memory in your program.

清风夜微凉 2024-08-13 18:24:35

您可以使用正则表达式。

#!/usr/bin/perl

use strict;
use warnings;

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

while ($s =~ m'^(.*)

或者你可以使用split

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

  # ...

}
gm) { print "'$1'\n"; } die "Exited loop too early\n" unless pos $s == length $s;

或者你可以使用split

You could use a regex.

#!/usr/bin/perl

use strict;
use warnings;

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

while ($s =~ m'^(.*)

Or you could use split:

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

  # ...

}
gm) { print "'$1'\n"; } die "Exited loop too early\n" unless pos $s == length $s;

Or you could use split:

短叹 2024-08-13 18:24:35

就我个人而言,我喜欢使用 $/ 来分隔行在多行字符串中。

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

Personally I like using $/ to separate the lines in a multiline string.

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;
  ...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文