Как печать Perl может добавить новую строку по умолчанию?

81

В Perl большинство моих операторов print принимают форму

print "hello." . "\n";

Есть ли хороший способ избежать того, чтобы все надоедливые "\n" лежали?

Я знаю, что могу создать новую функцию, такую ​​как myprint, которая автоматически добавляет \n, но было бы неплохо, если бы я мог переопределить существующий print.

  • 9
    Если ваш ответ содержит $ \, пожалуйста, убедитесь, что он содержит список предостережений относительно установки глобальных переменных с невидимым эффектом. Хотя он очень умный и технически отвечает на вопрос, его также очень опасно передавать без квалификации новичку.
  • 1
    perldoc perlvar описывает большинство предостережений, зачем их здесь приводить?
Показать ещё 6 комментариев
Теги:
printing
newline

9 ответов

90
Лучший ответ

Perl 6 имеет функцию say, которая автоматически добавляет \n.

Вы также можете использовать say в Perl 5.10 или 5.12, если вы добавите

use feature qw(say);

в начало вашей программы. Или вы можете использовать Modern:: Perl, чтобы получить эту и другие функции.

Подробнее см. perldoc.

  • 2
    +1 за упоминание необходимого пакета
  • 6
    Фактически, все, что вам нужно сделать, это use 5.012; или use 5.010; чтобы получить его, если вы используете эти новые perl .
Показать ещё 1 комментарий
29

Вы можете использовать опцию -l в заголовке she-bang:

#!/usr/bin/perl -l

$text = "hello";

print $text;
print $text;

Вывод:

hello
hello
  • 3
    Очень хорошо. Подробнее о параметрах perl , в том числе о том, что делает -l , здесь .
  • 1
    Поскольку это глобально, это плохая практика для всего, кроме однострочных и самых маленьких скриптов.
22

Если Perl 5.10+ не является вариантом, это быстрое и грязное приближение. Это не совсем то же самое, поскольку, скажем, имеет некоторую магию, когда его первым аргументом является дескриптор, но для печати в STDOUT:

sub say {print @_, "\n"}

say 'hello';
18

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

print "hello.\n";

Эта реализация, вероятно, упростит вашу кодировку в целом.

В дополнение к использованию use feature "say" или use 5.10.0 или use Modern::Perl, чтобы получить встроенную функцию say, я собираюсь сутенером perl5i, который по умолчанию включает много разумных отсутствующих функций Perl 5.

  • 11
    facepalm.jpg ...
9

Возможно, вы хотите изменить разделитель выходной записи на строку с помощью:

local $\ = "\n";

$ perl -e 'print q{hello};print q{goodbye}' | od -c
0000000    h   e   l   l   o   g   o   o   d   b   y   e                
0000014
$ perl -e '$\ = qq{\n}; print q{hello};print q{goodbye}' | od -c
0000000    h   e   l   l   o  \n   g   o   o   d   b   y   e  \n        
0000016

Обновление: мой ответ говорит о возможностях, а не о целесообразности. Я не считаю, что добавление "\n" в конце строк должно быть "надоедливым" хором, но если кто-то действительно хочет их избежать, это один из способов. Если бы я должен был поддерживать немного кода, который использует эту технику, я бы, вероятно, реорганизовал его pronto.

  • 5
    или просто perl -le 'print q{hello};print q{goodbye}'
  • 6
    Нет, пожалуйста, не делай этого. Хотя это технически правильный ответ, использование специальной переменной для чего-то столь же тривиального, как это является бременем обслуживания в будущем.
Показать ещё 4 комментария
3

В Perl 6 есть функция say

  • 14
    Это тоже в 5.010 :-)
  • 0
    @ nc3b Ах, удобно
1

Если вы застряли с pre-5.10, то приведенные выше решения не будут полностью реплицировать функцию say. Например

sub say { print @_, "\n"; }

Не будет работать с вызовами, такими как

say for @arr;

или

for (@arr) {
    say;
}

... потому что вышеприведенная функция не действует на неявный глобальный $_ как print и реальную функцию say.

Чтобы более точно воспроизвести perl 5.10+ say, вам нужна эта функция

sub say {
    if (@_) { print @_, "\n"; }
    else { print $_, "\n"; }
}

Теперь он действует как

my @arr = qw( alpha beta gamma );
say @arr;
# OUTPUT
# alphabetagamma
#
say for @arr;
# OUTPUT
# alpha
# beta
# gamma
#

say встроенный в perl6 ведет себя несколько иначе. Вызов с помощью say @arr или @arr.say будет не просто конкатенацией элементов массива, но вместо этого распечатает их, разделенные разделителем списка. Чтобы воспроизвести это в perl5, вы сделаете это

sub say {
    if (@_) { print join($", @_) . "\n"; }
    else { print $_ . "\n"; }
}

$" - это глобальная переменная разделителя списков, или если вы используете English.pm, то есть $LIST_SEPARATOR

Теперь он будет больше похож на perl6, так

say @arr;
# OUTPUT
# alpha beta gamma
#
0

Вот что я нашел на https://perldoc.perl.org/perlvar.html:

$\Разделитель выходных записей для оператора печати. Если определено, это значение печатается после последнего аргумента печати. По умолчанию это undef.

Вы не можете вызывать output_record_separator() для дескриптора, только как статический метод. Смотрите IO :: Handle.

Мнемоника: вы устанавливаете $\вместо добавления "\n" в конце печати. Кроме того, это так же, как $/, но это то, что вы получаете "обратно" из Perl.

пример:

$\ = "\n";
print "a newline will be appended to the end of this line automatically";
0

Вы можете написать более читаемую форму использования 5.010:

use v5.10;

Ещё вопросы

Сообщество Overcoder
Наверх
Меню