Почему в Perl я не могу использовать строку как ссылку SCALAR в качестве строгой ссылки? - PullRequest
5 голосов
/ 27 октября 2010
use strict;
my @array=('f1','f2','f3');
my $dir ='\tmp';
foreach (@array) {
my $FH = $_;
open ("$FH", ">$dir/${FH}.txt") or die $!;
}

foreach (@array) {
 my $FH = $_;
 close($FH);
}

я получил "Can't use string ("f1") as a symbol ref while "strict refs" in use at bbb.pl line 6." ошибку. Что такое исус?

Ответы [ 2 ]

6 голосов
/ 27 октября 2010

Во-первых: открытие 2 арг - это плохо, открытие 3 арг - лучше.

open( .. , ">", "$dir/${FN}.txt")   

во-вторых, что вы делаете с открытым ("$ FH" ..

аргумент 1, который нужно открыть, предполагается, что это настоящий дескриптор файла, который можно подключить к потоку данных. передача строки не будет работать.

INSANE:  open( "Hello world", .... )  # how can we open hello world, its not a file handle
WORKS:   open( *FH,.... )  # but don't do this, globs are package-globals and pesky
BEST:    open( my $fh, .... ) # and they close themself when $fh goes out of scope! 

третий

foreach my $filename ( @ARRAY ){ 
}

Далее:

dir = \tmp? уверены ли вы? Я думаю, что вы имели в виду /tmp, \tmp это что-то совсем другое.

Пятый:

use warnings;

Использование строгого кода хорошо, но вы должны также использовать предупреждения.

Шестое: используйте имена переменных, которые являются пояснительными, мы знаем, что @ является массивом, @array не более полезен.

ВСЕ ВМЕСТЕ

use strict;
use warnings;

my @filenames=('f1','f2','f3');
my @filehandles = ();
my $dir ='/tmp';
foreach my $filename (@filenames) {
   open (my $fh,'>', "${dir}/${filename}.txt") or die $!;
   push @filehandles, $fh;
}
# some code here, ie: 
foreach my $filehandle ( @filehandles ) { 
   print {$filehandle}  "Hello world!";
}
# and then were done, cleanup time
foreach my $filehandle ( @filehandles ){ 
   close $filehandle or warn "Closing a filehandle didn't work, $!";
}

В качестве альтернативы, в зависимости от того, что вы пытались сделать, этот код мог бы быть лучше:

use strict;
use warnings;

my @filenames=('f1','f2','f3');
my $dir ='/tmp';
foreach my $filename (@filenames) {
   open (my $fh,'>', "${dir}/${filename}.txt") or die $!;
   print {$fh}  "Hello world!";
}

Я явно не закрываю $ fh, потому что он не нужен, как только $ fh выходит из области видимости (в конце блока в этом случае), он автоматически закрывается.

6 голосов
/ 27 октября 2010

Вы используете строку "f1" в качестве первого аргумента для open, который ожидает дескриптор файла.

Вы, вероятно, хотели сделать:

my @filehandles = (); # Stash filehandles there so as to not lose filenames
foreach (@array) {
    my $FH = $_;
    open (my $fh, ">", "$dir/${FH}.txt") or die $!;
    push @filehandles, $fh;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...