I'm trying to figure out the proper PBP approved way to process a multi line string one line at a time. Many Perl coders suggest treating the multi line string as a filehandle, which works fine unless you have "use strict" in your script. Then you get a warning from the compiler about not being able to use a string as a symbol while strict refs is in use.
Here's a simple working example of the problem:
#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";
Notice that the "use strict" line is commented out. When I run this script without use strict, I get what I want and expect:
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
Here's the problem, though. When I uncomment the "use strict" line, I get the following warning or error from 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.
Line 8 is the "open $ResultsHandle, '<', \$return;" line, by the way. So since Perl Best Practices requires me to use strict, how does PBP expect me to process a multi line string one line at a time? Any suggestions from the SO community?
Thanks!
Don't initialise $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";
If you leave $ResultsHandle
undefined before the open()
, it will be filled in with a reference to the file handle. Because you were setting it to a string, open()
presumed that it was supposed to be a symbolic reference to a variable instead --- not allowed under use strict
.
The more succinct PBP way is to use open like so:
open my $ResultsHandle, '<', \$return;
This eliminates the need for that earlier "my $Resultshandle;" declaration and avoids incurring that strict warning that you ran into.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With