Проблемы с перлом и глобальными файлами - PullRequest
2 голосов
/ 15 июня 2009

Хорошо, у меня есть небольшая проблема здесь. Я понимаю, что мне не нужно устанавливать $ handle для * :: HTML, чтобы заставить этот фрагмент работать, однако этот код вырван из контекста при его использовании, и мне действительно нужно, чтобы он работал с $ handle. Выходные данные, которые я получаю, находятся ниже фрагмента, однако я хочу, чтобы файл file.html содержал «what \ nsometext1 \ nsometext2 \ n».

open(HTML, ">file.html");
$handle = \*::HTML;
print $handle "what\n";

open(READ, "< somefile.txt"); #somefile.txt contains sometext1\nsometext2\n
while(<READ>)
{
    print $handle;
}
close READ;
close HTML;

file.html остается с выводом «что», и GLOB (0x6278b0) GLOB (0x6278b0) печатается в окне терминала.

Ответы [ 5 ]

11 голосов
/ 15 июня 2009

Если вы посмотрите документацию для print, вы увидите, что есть три допустимых способа вызова print:

  • печать СПИСОК ФАЙЛАНДОВ
  • распечатать СПИСОК
  • печать

Только последняя версия печатает $_ неявно. Причина этого проста: Perl не может определить, хотите ли вы напечатать файловый дескриптор или файловый дескриптор без дополнительной информации (пробел, разделяющий файловый дескриптор и список). Печать дескриптора файла (а не к нему) является наиболее гибким методом, поэтому они выбрали это разрешение неоднозначного случая.

5 голосов
/ 15 июня 2009

Когда вы используете скалярные переменные для хранения файловых дескрипторов, вы должны помочь Perl понять, как анализировать выражение. Сказать print $var неоднозначно. Это может означать одно из следующего:

print STDOUT $var;  # print the contents of $var to STDOUT
print {$var} $_;    # print the contents of $_ to the handle $var

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

Более того, Perl использует переменную по умолчанию $_ только тогда, когда вы не указываете аргументы для печати. Из-за того, как print $var интерпретируется, $_ не используется.

3 голосов
/ 15 июня 2009

Оператор печати Perl's допускает пропуск LIST во всех случаях. Рассмотрим:

$ perl -le '$_ = "foo!"; print STDOUT'
foo!

Но для парсера это выглядит как файловый дескриптор - в отличие от print $scalar, который может быть чем угодно во время выполнения. Если вы не уверены в синтаксическом разборе кода, введите его через B :: Deparse , как в

$ perl -MO=Deparse,-p try
while (defined(($_ = <READ>))) {
    print($_);
    print($handle);
    print(STDOUT $_);
}

Как написано, цикл содержит три вызова для печати: print, print $handle и print STDOUT.

Чтобы приблизиться к тому, что вы хотите, вы можете использовать выберите :

my $oldfh = select $handle;

while(<READ>)
{
    print;
}

select $oldfh;

Обратите внимание, что select возвращает ранее выбранный дескриптор файла, а приведенный выше код сохраняет его, чтобы вернуть вещи туда, где мы их нашли позже.

1 голос
/ 15 июня 2009
use strict;
use warnings;

open( my $html, '>', "file.html" );
print $html "what\n";

open( my $read, '<', "somefile.txt" ); #somefile.txt contains sometext1\nsometext2\n

while( my $line = <$read> )    {
    print {$handle} $line;
}

close $read;
close $html;
1 голос
/ 15 июня 2009

Я понял это; Мне нужно $_ после $handle для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...