【问题标题】:How can Perl's print add a newline by default?Perl 的 print 如何默认添加换行符?
【发布时间】:2011-02-23 08:53:00
【问题描述】:

在 Perl 中,我的大部分 print 语句都采用这种形式

print "hello." . "\n";

有什么好方法可以避免让所有讨厌的“\n”到处乱放吗?

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

【问题讨论】:

  • 如果您的答案包括 $\,请确保它带有关于设置具有不可见效果的全局变量的警告列表。虽然它非常聪明并且在技术上回答了这个问题,但将不合格的人交给新手也非常危险。
  • perldoc perlvar 描述了大部分注意事项,为什么要在这里大谈特谈?
  • @David,因为一些随机的黑客会在这里搜索答案而不是 perldoc,对它们感到满意,甚至不知道警告!
  • 正是这种奇怪的推理导致我的熨斗贴上了警告标签,说我穿着它们时不应该熨烫衣服。
  • 现实生活中的工具有物理上的限制,生活在物理世界中的人们都相当了解这些限制。软件工具不受此类限制,也没有任何规则。他们可以做任何事情,并且经常表现出超出预期的行为,尤其是对于尚未了解合理预期界限的初学者。

标签: perl printing newline


【解决方案1】:

Perl 6 具有自动附加\nsay 函数。

如果你添加的话,你也可以在 Perl 5.10 或 5.12 中使用say

use feature qw(say);

到程序的开头。或者您可以使用Modern::Perl 来获取此功能和其他功能。

更多详情请见perldoc feature

【讨论】:

  • 事实上,如果您运行的是较新的perls,您只需use 5.012;use 5.010; 即可获得它。
  • 除非特别提到 Perl 6,否则问题是指 Perl 5,这不安全吗?
【解决方案2】:

您可以在 she-bang 标头中使用-l 选项:

#!/usr/bin/perl -l

$text = "hello";

print $text;
print $text;

输出:

hello
hello

【讨论】:

  • 非常好。有关perl 选项的更多信息,包括-l 正在做什么,here
【解决方案3】:

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

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

say 'hello';

【讨论】:

    【解决方案4】:

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

    print "hello.\n";
    

    总体而言,这种认识可能会使您的编码更容易。

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

      【讨论】:

      • 不,请不要那样做。虽然从技术上讲是一个正确的答案,但使用一个特殊的变量来处理像这样微不足道的事情是一个维护负担。
      • @tsee 实际上我完全同意。正如我编辑我的答案所表明的那样,我的答案描述了该功能,即使有人不建议将其作为一般做法。
      • 真正的危险来自这样一个事实,即所有代码现在都将添加换行符,甚至是其他人模块中没有预料到的代码。想象一下网络代码会发送消息"helo\r\n",现在发送"helo\r\n\n"
      • 当然你总是可以让它本地化以避免影响其他代码,但仍然想让你的子程序看起来更干净一点:local $\ = "\n";
      • 使用命令标志-l 非常适合命令行单行代码(请参阅perldoc.perl.org/perlrun.html#Command-Switches)。我不会在任何更大的程序中推荐它。
      【解决方案6】:

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

      【讨论】:

        【解决方案7】:

        在 Perl 6 中有 say 函数

        【讨论】:

          【解决方案8】:

          如果您坚持使用 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
          #
          

          perl6 中的 say 内置函数的行为略有不同。使用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
          #
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-03-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-08-04
            相关资源
            最近更新 更多