Что делает некоторое время после печати, средней в Perl?

Вещь № 1 IMO: Внимание на потокобезопасность . GIL CPYTHON делает пишущий ориентированный на многопотоковое исполнение код легким, потому что только один поток может получить доступ к интерпретатору за один раз. IronPython и Jython являются немного меньшим количеством содержания руки все же.

5
задан Peter Mortensen 5 April 2019 в 06:55
поделиться

7 ответов

Это то же самое, что и

while (<STUFF>) {
    print "Line $. is : $_";
}

Он написан так, как есть, потому что он проще и более компактный. В общем, это известная форма Perl (in) «модификатор оператора» для условных выражений и циклов.

11
ответ дан 18 December 2019 в 05:44
поделиться

В других ответах объясняется форма модификатора оператора , а петля. Однако здесь происходит много другого волшебства. В частности, сценарий полагается на три специальные переменные Perl. Два из них ( $ _ и $! ) очень распространены; другой ( $. ) довольно распространен. Но все они заслуживают внимания.

Когда вы запускаете , а <$ fh> на открытом дескрипторе файла, Perl автоматически запускает файл, строка за строкой, пока не достигнет EOF ]. В каждом цикле текущая строка установлена ​​на $ _ без каких-либо действий. Итак, это одно и то же:

while (<$fh>) { # something }
while (defined($_ = <$fh>)) { # something }

См. perldoc perlop , раздел об операторах ввода-вывода. (Некоторые люди находят это тоже волшебным, поэтому они используют вместо него while (my $ line = <$ fh>) . Это дает вам $ line для каждой строки а не $ _ , которое является более понятным именем переменной, но требует большего набора текста. Каждому свое.)

$! содержит значение системной ошибки (если она установлено). См. perldoc perlvar , раздел $ OS_ERROR , чтобы узнать, как и когда это использовать.

$. содержит номер строки. См. perldoc perlvar , раздел $ NR . Эта переменная может быть на удивление сложной. Это победило t обязательно иметь номер строки файла, который вы сейчас читаете. Пример:

#!/usr/bin/env perl
use strict;
use warnings;

while (<>) {
    print "$ARGV: $.\n";
}

Если вы сохраните это как lines и запустите как perl lines file1 file2 file3 , то Perl будет считать строки прямо через file1, file2 и file3. Вы можете видеть, что Perl знает, из какого файла он читает (он находится в $ ARGV; имена файлов будут правильными), но он не автоматически сбрасывает нумерацию строк в конце каждого файла. Я упоминаю об этом, поскольку меня это поведение не раз кусало, пока я наконец не прошел через свой (толстый) череп. Вы можете сбросить нумерацию для отслеживания отдельных файлов следующим образом:

#!/usr/bin/env perl
use strict;
use warnings;

while (<>) {
    print "$ARGV: $.\n";
}
continue {
    close ARGV if eof;
}

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

7
ответ дан 18 December 2019 в 05:44
поделиться

Я взял на себя смелость переписать ваш фрагмент, как и сделал бы.

Ниже предложенный мной код представляет собой галерею неоптимальных методов, которые вы можете встретить в реальной жизни.

use strict;
use warnings;

my $stuff_path = 'c:/scripts/stuff.txt';

open (my $stuff, '<', $stuff_path)
    or die "Cannot open'$stuff_path' for read : $!\n";

# My preferred method to loop over a file line by line:
# while loop with explicit variable
while( my $line = <$stuff> ) {
    print "Line $. is : $line\n";
}

Вот и другие методы, которые вы можете увидеть. Каждый из них может быть заменен на цикл while в моем примере выше.

# while statement modifier
# - OK, but less clear than explicit code above.
print "Line $. is : $_" while <$stuff>;

# while loop
# - OK, but if I am operating on $_ explicitly, I prefer to use an explicit variable.
while( <$stuff> ) {
   print "Line $. is : $_";
}

# for statement modifier 
# - inefficient
# - loads whole file into memory
print "Line $. is : $_" for <$stuff>;

# for loop - inefficient
# - loads whole file into memory;
for( <$stuff> ) {
    print "Line $. is : $_\n";
}

# for loop with explicit variable
# - inefficient
# - loads whole file into memory;
for my $line ( <$stuff> ) {
    print "Line $. is : $line\n";
}

# Exotica -

# map and print
# - inefficient
# - loads whole file into memory
# - stores complete output in memory
print map "Line $. is : $_\n", <$stuff>;

# Using readline rather than <>
# - Alright, but overly verbose
while( defined (my $line = readline($stuff) ) {
    print "Line $. is : $line\n";    
}

# Using IO::Handle methods on a lexical filehandle
# - Alright, but overly verbose
use IO::Handle;   
while( defined (my $line = $stuff->readline) ) {
    print "Line $. is : $line\n";    
}
3
ответ дан 18 December 2019 в 05:44
поделиться

Следующие ниже фрагменты полностью эквивалентны, просто разные способы написания одного и того же:

print "Line $. is : $_" while (<STUFF>);

while (<STUFF>) {
    print "Line $. is : $_";
}

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

Line 1 is : test
Line 2 is : file

Специальная переменная $. - это номер последней строки, прочитанной из файла, а $ _ - это содержимое этой строки, заданное оператором угловой скобки.

4
ответ дан 18 December 2019 в 05:44
поделиться

Размещение и после печати делает строку читаемой почти как обычный английский.

Это также делает акцент на печати вместо и . И вам не нужны фигурные скобки: {...}

Их также можно использовать с if и , если , например,

print "Debug: foobar=$foobar\n" if $DEBUG;

print "Load file...\n" unless $QUIET;
4
ответ дан 18 December 2019 в 05:44
поделиться

Обратите внимание, что оператор while может следовать за телом вашего цикла, только если он однострочный. Если тело вашего цикла занимает несколько строк, то перед ним должен стоять , а .

1
ответ дан 18 December 2019 в 05:44
поделиться

Это то же самое, что и:

while (<STUFF>) { print "Line $. is: $_"; }
0
ответ дан 18 December 2019 в 05:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: