Perlのprintはデフォルトでどのように改行を追加できますか?


95

Perlでは、私のprintステートメントのほとんどが次の形式をとります

print "hello." . "\n";

すべての厄介な "\ n"を横に置いておくのを避ける良い方法はありますか?

私はmyprint自動的に\ nを追加するような新しい関数を作成できることを知っていますが、既存のをオーバーライドできればよいでしょうprint


10
回答に$ \が含まれている場合は、目に見えない効果を持つグローバル変数の設定に関する警告のリストが含まれていることを確認してください。非常に賢く、技術的には質問に答えますが、資格のない人を初心者に渡すことも非常に危険です。
Schwern、

1
perldoc perlvarは警告のほとんどを説明していますが、なぜここでそれらを非難するのですか?
デビッドM

5
@David、ランダムハッカーがperldocの代わりにここで答えをググって、満足し、警告についてさえ知らないからです!
Pは、

2
それがまさに、私がアイロンをしているときに衣服にアイロンをかけるべきではないという警告ラベルがアイロンに付いた、奇妙な推論のようなものです。
David M

8
現実のツールには物理的な制限があり、物理的な世界で生活してきた人々にはかなりよく理解されています。ソフトウェアツールにはそのような制限はなく、ルールはありません。彼らは何でもでき、期待外の行動をすることがよくあります。特に、妥当な期待の境界をまだ理解していない初心者にとっては特にそうです。
Ether

回答:


99

Perl 6はsay自動的に追加する機能を持っています\n

say追加すると、Perl 5.10または5.12 でも使用できます。

use feature qw(say);

プログラムの始めに。または、Modern :: Perlを使用して、この機能やその他の機能を取得することもできます。

詳細については、perldoc機能を参照してください。


7
実際、新しいsを実行している場合は、use 5.012;それuse 5.010;を取得するか、取得するだけですperl
ロバートP

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をしているのかなど、オプションの詳細については、こちらをご覧ください
ルフィン、2015年

1
これはグローバルであるため、ワンライナーと最も小さなスクリプト以外ではこれは悪い習慣です。
Schwern、2015

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」を追加することは「厄介な」雑用だとは思いませんが、誰かが本当にそれらを避けたい場合は、これが1つの方法です。この手法を使用する少しのコードを維持する必要がある場合は、おそらくそれを前もってリファクタリングするでしょう。


6
いいえ、しないでください。技術的には正しい答えですが、特別な変数を使用することは、これからのメンテナンスの負担になるので、些細なことではありません。
tsee

1
@tsee私は実際に完全に同意します。答えを編集して示したように、一般的な方法としてはお勧めしませんが、私の答えは機能を説明しています。
デビッドM

本当の危険は、すべてのコードが改行を追加するという事実から来ています。期待していなかった他の人のモジュールのコードも。"helo\r\n"今送信するメッセージを送信するネットワークコードを想像してください"helo\r\n\n"
Chas。オーエンス

もちろん、あなたは常に他のコードへの影響を回避することがローカルにするが、それでもあなたのサブルーチンを少しきれいに見えるようにしたいこと:local $\ = "\n";
redbmk

コマンドフラグの使用は-l、コマンドラインのワンライナーに最適です(perldoc.perl.org/perlrun.html#Command-Switchesを参照)。大きなプログラムではお勧めしません。
djd

4

これが私がhttps://perldoc.perl.org/perlvar.htmlで見つけたものです:

$ \印刷演算子の出力レコード区切り記号。定義されている場合、この値は、printの最後の引数の後に印刷されます。デフォルトはundefです。

ハンドルでoutput_record_separator()を呼び出すことはできません。静的メソッドとしてのみ呼び出すことができます。IO :: Handleを参照してください。

記憶法:印刷の最後に「\ 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;
}

...上記の関数は、暗黙の大域的な$_like 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
#

sayPerl6の中に組み込みは少し異なる動作をします。say @arrorで呼び出すと@arr.say、配列項目が連結されるだけでなく、リストのセパレーターで区切られて出力されます。これをperl5で複製するには、次のようにします

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

$"グローバルリストセパレーター変数です。使用している場合English.pm$LIST_SEPARATOR

これで、perl6のように動作します。

say @arr;
# OUTPUT
# alpha beta gamma
#
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.