【问题标题】:Is it wrong to print $/ instead of \n?打印 $/ 而不是 \n 有错吗?
【发布时间】:2015-07-13 16:39:16
【问题描述】:

Perl 的文档说 $/ 是:

输入记录分隔符,默认换行。这会影响 Perl 的 了解什么是“线”。

那么,这样做基本上是错误的:

print STDERR $var, $/;

代替:

print STDERR "$var\n";

?

如果我做前者会出什么问题?

【问题讨论】:

  • 它是 input 分隔符,如果您需要读取 CRLF 或 CR 编码的文件,可能会对其进行操作。
  • $/ 是系统 eol 字符,如果您生成的文件仅用于“本地”使用,这很好。如果您正在为某些其他操作系统生成文件,例如你在 Linux 上构建一个 Windows 文件,那么 $/ 没用。
  • 你真的应该使用 output 记录分隔符$\,但我看不出这样做有什么问题。事实上,say function 就是这样做的:“say LIST 只是 { local $\ = "\n"; print LIST } 的缩写”(如果您使用的是 5.10+,我会使用 say 代替。)
  • @user3476791:不,Perl 尽力隐藏系统 eol 字符(或序列)并将其作为换行符 "\n" 呈现给您的 Perl 代码。当您要使用 <> 运算符检索的输入记录与文本行不一致时,将使用操作 $/。这就是为什么它被称为输入记录分隔符而不是输入行分隔符
  • @Borodin 是正确的,Mark B 是错误的。 $/ 在任何系统上默认为“\n”; CRLF 翻译通常在 I/O 函数中处理,因此您的代码只会看到/产生“\n”

标签: perl newline


【解决方案1】:

也许您正在寻找输出记录分隔符?

perldoc perlvar:

 IO::Handle->output_record_separator(EXPR)
   $OUTPUT_RECORD_SEPARATOR
   $ORS
   $\

打印操作符的输出记录分隔符。 如果已定义,则在 print 的最后一个参数之后打印此值。默认为“undef”。

您不能在句柄上调用“output_record_separator()”,只能作为静态方法。见IO::Handle

助记符:您设置了“$\”而不是在打印末尾添加“\n”。此外,它就像 $/,但它是您从 Perl 中“返回”的内容。

例如,

$\ = $/;
print STDERR $var;

【讨论】:

  • 我认为这是一个非常糟糕的主意。没有多少模块可以保护自己免受 $\ 更改的影响,因此全局更改 $\ 会破坏它们。您可以使用{ local $\ = $/; print STDERR $var; } 限制更改的范围,但与print STDERR "$var\n";say STDERR $var; 相比,这完全是一团糟。
  • @ikegami 而且我认为如果模块无法处理 $\­ 的变化,那是模块中的一个错误,特别是考虑到有一个常用的命令行选项确实设置了 $\­ (-l)。
  • @hvd,可能在单行中常用,但我怀疑很少有模块在每个 print 之前执行 local $/;,因为这样做很愚蠢,即使您考虑这是一个错误。
【解决方案2】:

$/ 默认为 LF (U+000A)。这与"\n"[1] 产生的字符相同。所以除非你改变了$/$/"\n" 是等价的。如果您确实更改了$/,那么只有您知道原因,因此只有您知道$/ 还是"\n" 更合适。


  1. 在古老的 MacOS 机器上,$/ 的默认值是 CR (U+000D),但这也是 "\n" 在那里产生的。

【讨论】:

    【解决方案3】:

    xxfelixxx 已回答,您需要输出记录分隔符 $\。

    $/ 你读的是input record separator。操作它会影响 Perl 读取您提供的文件数据的方式。例如:

    open my $fh, "<", $filename or die $!;
    local $/; # enable localized slurp mode
    my $content = <$fh>;
    close $fh;
    

    由于我们已经重置了$/,上述导致文件的整个内容以标量$content slurp。

    考虑下面的代码:

    #!/usr/bin/perl
    use strict;
    use warnings;
    my $content;
    {local $/; $content = <DATA>}
    print "Content is $content";
    __DATA__
    line 1
    line 2
    line 3
    

    输出:

    Content is line 1
    line 2
    line 3
    

    但是如果你不重置 $/,就像下面的代码:

    #!/usr/bin/perl
    use strict;
    use warnings;
    my $content = <DATA>;
    print "Content is $content";
    __DATA__
    line 1
    line 2
    line 3
    

    输出将是Content is line 1

    这是因为输入记录分隔符设置为换行符,并且在第一行之后返回。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-07
      • 2018-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多