Як друк Perl може додати новий рядок за замовчуванням?


95

У Perl більшість моїх printзаяв приймають форму

print "hello." . "\n";

Чи є приємний спосіб уникнути того, щоб усі дотепні "\ n" лежали навколо?

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


10
Якщо Ваша відповідь включає $ \, будь ласка, переконайтеся, що вона містить список застережень щодо встановлення глобальних змінних з невидимим ефектом. Незважаючи на те, що дуже розумний і технічно відповідає на питання, його також дуже небезпечно передавати новачкові некваліфіковано.
— Schwern

1
perldoc perlvarописує більшість застережень, навіщо їх тут робити?
— Девід М

5
@David, тому що якийсь випадковий хакер перегляне тут відповіді замість perldoc, задовольниться ними і навіть не дізнається про застереження!
— П Швед

2
Це саме такі химерні міркування, що призвели до того, що моя праска мала попереджувальну етикетку, що я не повинен прасувати одяг, поки я їх ношу.
— Девід М

8
Інструменти реального життя мають фізичні обмеження, які досить добре розуміють люди, які прожили своє життя у фізичному світі. Програмні засоби не обмежуються такими обмеженнями, і немає ніяких правил. Вони можуть робити все, що завгодно, і часто поводяться поза сподіваннями, особливо для початківців, які ще не вивчили межі розумних очікувань.
— Ефір

Відповіді:


99

Perl 6 має sayфункцію, яка автоматично додається \n.

Ви також можете використовувати sayв Perl 5.10 або 5.12, якщо додати

use feature qw(say);

до початку вашої програми. Або ви можете використовувати Modern :: Perl, щоб отримати цю та інші функції.

Докладніше див. У функції Perldoc .


7
Насправді все, що вам потрібно зробити, - це use 5.012;або use 5.010;отримати його, якщо ви працюєте з тими новішими perl.
— Роберт П

Хіба не можна припустити, що якщо Perl 6 конкретно не згадується, що питання стосується Perl 5?
— wobbily_col

35

Ви можете використовувати -lпараметр у заголовку she-bang:

#!/usr/bin/perl -l

$text = "hello";

print $text;
print $text;

Вихід:

hello
hello

3
Дуже хороша. Більше про perlваріанти, зокрема про те, що -lробиться, тут .
— ruffin

1
Оскільки це глобально, це погана практика в чому-небудь, крім однолінійки та найменшого сценарію.
— Шверн

24

Якщо Perl 5.10+ не є варіантом, ось швидке та брудне наближення. Це не зовсім те саме, оскільки say має певну магію, коли його перший аргумент - це ручка, але для друку в STDOUT:

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

say 'hello';

20

Те, як ви пишете свою друковану заяву, необов'язково багатослівне. Не потрібно відокремлювати новий рядок у власному рядку. Цього достатньо.

print "hello.\n";

Ця реалізація, ймовірно, полегшить ваше кодування в цілому.

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


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.


6
Ні, будь ласка, не робіть цього. Хоча технічно правильна відповідь, використання спеціальної змінної для чогось такого тривіального, як це є тягарем технічного обслуговування в дорозі.
— tsee

1
@tsee Я згоден повністю, насправді. Коли я редагував свою відповідь, щоб вказати, моя відповідь описує можливість, навіть якщо хтось не рекомендував би її як загальну практику.
— Девід М

Справжня небезпека походить від того, що весь код тепер буде додавати нові рядки, навіть код в модулях інших людей, які цього не очікували. Уявіть собі мережевий код, який послав би повідомлення, "helo\r\n"яке зараз надсилає "helo\r\n\n".
— Час. Оуенс

Звичайно, ви завжди можете зробити його локальним, щоб не впливати на інший код, але все ж хочете, щоб ваша підпрограма виглядала трохи чистішою:local $\ = "\n";
— redbmk

Використання прапора команди -lвідмінно підходить для одноклассників командного рядка (див. Perldoc.perl.org/perlrun.html#Command-Switches ). Я б не рекомендував це в будь-якій більшій програмі.
— дед

4

Ось що я знайшов на https://perldoc.perl.org/perlvar.html :

$ \ Розділювач виводу запису для оператора друку. Якщо визначено, це значення друкується після останнього аргументу друку. За замовчуванням значення undef.

Ви не можете викликати output_record_separator () на дескрипторі, лише як статичний метод. Див. IO :: Ручка.

Мнемоніка: ви встановлюєте $ \ замість того, щоб додавати "\ n" в кінці друку. Крім того, це як $ /, але це те, що ви отримуєте "назад" від Perl.

приклад:

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


1

Якщо ви застрягли в попередній версії 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
#
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.