如何使用严格到位的perl一次处理一行多行字符串?

Kur*_*cht 8 string perl multiline filehandle

我试图弄清楚正确的PBP批准的方法,一次处理一行多行字符串.许多Perl程序员建议将多行字符串视为文件句柄,除非你的脚本中有"use strict",否则它可以正常工作.然后,您会收到编译器的警告,指出在使用严格的refs时无法使用字符串作为符号.

这是一个简单的问题工作示例:

#use strict;
use warnings; 

my $return = `dir`;
my $ResultsHandle = "";
my $matchLines = "";
my $resultLine = "";
open $ResultsHandle, '<', \$return;
while (defined ($resultLine = <$ResultsHandle>)) {
    if ($resultLine =~ m/joe/) {
        $matchLines = $matchLines . "\t" . $resultLine;
    }
}
close($ResultsHandle);
print "Original string: \n$return\n";
print "Found these matching lines: \n$matchLines\n";
Run Code Online (Sandbox Code Playgroud)

请注意,"use strict"行已注释掉.当我在没有使用严格的情况下运行此脚本时,我得到了我想要的和期望的:

Original string: 
 Volume in drive D has no label.
 Volume Serial Number is 50D3-54A6

 Directory of D:\Documents and Settings\username\My Documents\Eclipse\myTestProject

09/18/2009  11:38 AM    <DIR>          .
09/18/2009  11:38 AM    <DIR>          ..
09/18/2009  11:36 AM               394 .project
09/18/2009  11:37 AM                 0 joe.txt
09/18/2009  11:37 AM                 0 joey.txt
09/18/2009  11:38 AM                 0 kurt.txt
09/18/2009  11:43 AM               497 main.pl
09/18/2009  11:38 AM                 0 shane.txt
               6 File(s)            891 bytes
               2 Dir(s)   6,656,188,416 bytes free

Found these matching lines: 
    09/18/2009  11:37 AM                 0 joe.txt
    09/18/2009  11:37 AM                 0 joey.txt
Run Code Online (Sandbox Code Playgroud)

不过这是问题所在.当我取消注释"use strict"行时,我从Perl收到以下警告或错误:

Can't use string ("") as a symbol ref while "strict refs" in use at D:/Documents and Settings/username/My Documents/Eclipse/myTestProject/main.pl line 8.
Run Code Online (Sandbox Code Playgroud)

第8行是"打开$ ResultsHandle,'<',\ $ return;" 顺便说一下.因此,由于Perl Best Practices要求我使用严格,PBP如何期望我一次处理一行多行字符串?来自SO社区的任何建议?

谢谢!

dav*_*420 11

不要初始化$ResultsHandle:

use strict;
use warnings; 

my $return = `dir`;
my $ResultsHandle;  # <-- leave undefined
my $matchLines = "";
my $resultLine = "";
open $ResultsHandle, '<', \$return;
while (defined ($resultLine = <$ResultsHandle>)) {
    if ($resultLine =~ m/joe/) {
        $matchLines = $matchLines . "\t" . $resultLine;
    }
}
close($ResultsHandle);
print "Original string: \n$return\n";
print "Found these matching lines: \n$matchLines\n";
Run Code Online (Sandbox Code Playgroud)

如果$ResultsHandle在之前保留undefined open(),则会使用对文件句柄的引用填充它.因为你把它设置为一个字符串,open()假定它应该是一个变量的符号引用 - 不允许在下面use strict.

  • 另一种思考方式:`open()`为你初始化`$ ResultsHandle`,*如果它尚未初始化*.`use strict`不允许偶尔使用的东西,但往往会造成麻烦. (2认同)

dra*_*tun 7

更简洁的PBP方式是使用open这样:

open my $ResultsHandle, '<', \$return;
Run Code Online (Sandbox Code Playgroud)

这消除了对早期"my $ Resultshandle"的需求.声明并避免招致您遇到的严格警告.