Why do I get a syntax error when I want to print to a handle in a hash key?
-
25-06-2021 - |
Pregunta
I have code which stores all the files handles for files in the current directory as values in a hash. The keys are the names of the files.
my %files_list; #this is a global variable.
sub create_hash() {
opendir my $dir, "." or die "Cannot open directory: $!";
my @files = readdir $dir;
foreach (@files) {
if (/.text/) {
open(PLOT, ">>$_") || die("This file will not open!");
$files_list{$_} = *PLOT;
}
}
}
Down the line I am using print statements in my code where I am facing some compilation issues.
my $domain = $_;
opendir my $dir, "." or die "Cannot open directory: $!";
my @files = readdir $dir;
foreach (@files) {
if (/.text/ && /$subnetwork2/) {
print $files_list{$_} "$domain"; #this is line 72 where there is error.
}
}
closedir $dir;
The compilation errors are below:
String found where operator expected at process.pl line 72, near "} "$domain""
(Missing operator before "$domain"?)
syntax error at process.pl line 72, near "} "$domain""
Could anyone please help me understand the fault?
Solución
first problem:
After running create_hash
subroutine you would have %files_list
filled up with *PLOT
in all keys.
all print {$files_list{$_}} "$domain";
whould print into last opened file.
solution:
-open(PLOT,">>$_") || die("This file will not open!");
-$files_list{$_}=*PLOT;
+open($files_list{$_},">>$_") || die("This file will not open!");
second problem:
you don't check that file descriptor exists before printing into it
solution:
-if(/.text/ && /$subnetwork2/)
-{
- print $files_list{$_} "$domain";#this is line 72 where there is error.
+if(/.text/ && /$subnetwork2/ && exists $files_list{$_})
+{
+ print {$files_list{$_}} $domain;
and don't forget about closing file handles...
Otros consejos
Maybe you should read the documentation for print. The final paragraph says:
If you're storing handles in an array or hash, or in general whenever you're using any expression more complex than a bareword handle or a plain, unsubscripted scalar variable to retrieve it, you will have to use a block returning the filehandle value instead, in which case the LIST may not be omitted:
print { $files[$i] } "stuff\n"; print { $OK ? STDOUT : STDERR } "stuff\n";
Maybe as this:
print {$files_list{$_}} "$domain";