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

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

print "hello." . "\n";

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

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

Ответ 1

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

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

use feature qw(say);

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

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

Ответ 2

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

#!/usr/bin/perl -l

$text = "hello";

print $text;
print $text;

Вывод:

hello
hello

Ответ 3

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

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

say 'hello';

Ответ 4

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

print "hello.\n";

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

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

Ответ 5

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

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.

Ответ 6

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

Ответ 7

Если вы застряли с 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
#

Ответ 8

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

use v5.10;

Ответ 9

Вот что я нашел на 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";