默认情况下,Perl的印刷品如何添加换行符?


95

在Perl中,我大部分的print陈述采用以下形式

print "hello." . "\n";

有什么好方法可以避免使所有讨厌的\ n散布?

我知道我可以创建一个新函数,例如myprint自动追加\ n,但是如果我可以覆盖现有函数,那就太好了print


10
如果您的答案包含$ \,请确保附带了有关设置具有隐形效果的全局变量的注意事项列表。尽管它非常聪明并且从技术上回答了这个问题,但将不合格的新手交给新手也很危险。
Schwern,2010年

1
perldoc perlvar描述了大多数警告,为什么要在这里加以说明?
David M

5
@David,因为有些随机的黑客会在这里搜索答案而不是perldoc,对它们感到满意,甚至不知道警告!
P

2
这恰恰是一种奇怪的推理,导致我的熨斗有警告标签,说我穿衣服时不应该熨烫衣服。
David M

8
现实生活中的工具具有一定的物理局限性,而那些生活在物理世界中的人们则可以很好地理解它们。软件工具不受这些限制的约束,也没有任何规则。他们可以做任何事情,并且经常表现超出预期,特别是对于尚未了解合理预期范围的初学者。
以太2010年

Answers:


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秒。
罗伯特·P

除非特别提到Perl 6,否则假设不是针对Perl 5的,那不是安全的假设吗?
wobbily_col

35

您可以使用-lshe-bang标头中的选项:

#!/usr/bin/perl -l

$text = "hello";

print $text;
print $text;

输出:

hello
hello

3
非常好。此处提供有关perl选项的更多信息,包括-l正在做什么。
鲁芬,2015年

1
因为它是全球性的,所以在单行和最小的脚本之外的任何情况下,这都是不好的做法。
Schwern 2015年

24

如果不能选择Perl 5.10+,这是一个快速而肮脏的近似值。这并不完全相同,因为当第一个arg是句柄时,say拥有一些魔力,但可以打印到STDOUT:

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

say 'hello';

20

您编写打印语句的方式不必要地冗长。无需将换行符分隔为自己的字符串。这样就足够了。

print "hello.\n";

通常,这种实现可能会使您的编码更容易。

除了使用use feature "say"or或use 5.10.0or 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”是一件令人讨厌的事情,但是如果有人真的想避免使用它们,这是一种方法。如果我必须维护一些使用该技术的代码,那么我可能会立即将其重构。


6
不,请不要那样做。从技术上讲,这是正确的答案,但对于一些琐碎的事情使用特殊的变量会给您带来很大的维护负担。
tsee

1
@tsee实际上,我完全同意。当我编辑答案以指示该内容时,我的答案描述了该功能,即使不建议将其作为一般惯例。
David M

真正的危险来自这样一个事实,即所有代码现在都将添加换行符,甚至是其他人不期望的模块中的代码。想象一下将发送"helo\r\n"现在发送的消息的网络代码"helo\r\n\n"
Chas。欧文斯(Owens)2010年

当然,您始终可以将其设置为本地以避免影响其他代码,但仍想使子例程看起来更local $\ = "\n";
简洁

-l对于命令行一线式命令,使用命令标志非常有用(请参阅perldoc.perl.org/perlrun.html#Command-Switches)。我不会在任何更大的程序中推荐它。
2012年

4

这是我在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";


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
#

sayperl6中的内置行为有所不同。使用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
#
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.