Perl: Цикл по файловым дескрипторам

Я самоучка Perl, ищу помощи у экспертов Perl:

Я продолжаю получать сообщение об ошибке, говорящее, что я не могу использовать дескриптор файла в цикле foreach, хотя я уверен, что это close (или undef, я пробовал оба). Полный текст ошибки см. здесь: http://cl.ly/image/2b2D1T403s14

Код доступен на GitHub: https://github.com/bsima/yeast-TRX.

Рассматриваемый код можно найти в файле «script.pl» примерно в строке 90:

foreach my $species (keys %Saccharomyces) {
    open(RAW,">./data/$species/$geneName/raw.csv");
        print RAW "gene,dinucleotide,position,trx.score,energy.score\n";
    undef RAW; 
    open(SMOOTH,">./data/$species/$geneName/smooth.csv");
        print SMOOTH "gene,position,trx.score,energy.score\n";
    undef SMOOTH;
}

Помощь очень ценится! Я не знаю тонкостей того, как Perl работает с файловыми дескрипторами, вероятно, из-за отсутствия у меня формального обучения. Приветствуются любые комментарии по поводу общего качества моего кода, если кто-то чувствует себя особенно полезным.

РЕДАКТИРОВАТЬ: Нашел проблему. Perl не может генерировать каталоги на лету, поэтому каталог $species/$geneName никогда не создавался. Я добавил строку в начале цикла foreach, в которой говорилось просто mkdir("$species/$geneName");, и это решило проблему.


person Ben    schedule 11.10.2013    source источник
comment
Беглый взгляд на perldoc -f undef перечисляет виды вещей, на которых вы можете его использовать. Файловые дескрипторы Bareword не входят в этот список. Прислушайтесь к совету MVP и используйте close и лексические файловые дескрипторы.   -  person tjd    schedule 11.10.2013


Ответы (2)


Вы получаете предупреждение, которое довольно красноречиво:

Bareword RAW не разрешен, пока используются «строгие сабвуферы»

Кроме того, undef FILEHANDLE не так хорош, как close FILEHANDLE.

Решение состоит в том, чтобы использовать обычные переменные с областью видимости для файловых дескрипторов и закрывать их, примерно так:

foreach my $species (keys %Saccharomyces) {
    open my $raw, ">", "./data/$species/$geneName/raw.csv";
    print $raw "gene,dinucleotide,position,trx.score,energy.score\n";
    close $raw;
    open my $smooth, ">", "./data/$species/$geneName/smooth.csv";
    print $smooth "gene,position,trx.score,energy.score\n";
    close $smooth;
}

Кроме того, вы должны проверить, были ли открыты $raw и $smooth, прежде чем пытаться писать в них.

person mvp    schedule 11.10.2013
comment
Я пробовал это. К сожалению, я получаю сообщение об ошибке, говорящее о том, что я пытаюсь распечатать ранее закрытый дескриптор файла: скриншот - person Ben; 12.10.2013
comment
Я думал, что undef позволит мне открыть отдельный файл и повторно использовать my $raw или my $smooth, но, похоже, это не так. - person Ben; 12.10.2013
comment
Это не имеет никакого смысла, и на вашем снимке экрана по-прежнему показан глобальный дескриптор файла GENEFILE. Код open my $fd, ">", filename; print $fd "text"; close $fd; не может дать сбой, если у вас есть разрешение на создание $filename в первую очередь. Пожалуйста, покажите ваш реальный код. - person mvp; 12.10.2013

Perl не может генерировать каталоги на лету, поэтому каталог $species/$geneName никогда не создавался. Я добавил строку в начале цикла foreach, в которой говорилось просто mkdir("$species/$geneName");, и это решило проблему.

person Ben    schedule 13.10.2013