设置一个文件句柄,以便安静地跳过它的打印?

时间:2016-02-29 00:51:33

标签: perl filehandle

这种奇怪的兴趣来自于扩展需求,没有时间改变设计(重构)。这肯定不是好设计,但我现在需要处理它并希望以后重构。

早期打开了一些日志文件,打印到整个代码中。新要求意味着使用(新)命令行选项(--noflag),其中一个日志文件无关紧要。

目前我所能做的就是用open my $fh, ...填充定义(print $fh ...)和的所有用途if $flag)。这显然是糟糕的设计,并且容易出错(它也不是很好)。

当与文件关联时,是否可以使用$fh执行某些操作 以便任何后续print $fh ...被解释器接受,但会导致只是没有运行print,没有错误? (让我想象一下,比如,$fh = VOID if $flag;。或者,是否有一些NULL流或类似的?我所知道的只有STDOUT(1),STDERR(2)和STDIN(0)。

我不希望$fh在其他任何地方打印,理想情况下甚至不能/dev/null(如果可能的话?)。我确实环顾四周,找不到任何相关的东西。如果事实上它已经存在,我会很感激被指向的信息。 任何想法都表示赞赏。

PS。在这里问过的第一个问题(经过多年使用SO之后),请告诉我它是否已关闭。


更新

感谢您的回复。他们提示我添加/改进此问题:标记为/dev/null的打印件是否可能已经优化,以便打印'实际上并没有发生? (虽然我仍然感兴趣的是是否可以设置文件句柄以便告诉Perl'不要在这里打印'。)

我试图避免运行void(print)语句,而不添加条件。


更新/澄清

总结一下评论(谢谢!):这不是对性能优化的追求。我完全赞同在评论中所说的一切。简单地说,执行无意义的陈述(通常大约一百万)让我感到不安。此外,我很好奇Perl的一些可能的黑暗角落,我还没有遇到过。 (大部分内容已在答案/评论中得到解决。)

4 个答案:

答案 0 :(得分:3)

如果您使用的是unix操作系统,则可以使用'/ dev / null'

open my $fh, '>', '/dev/null' or die 'This should never happen';

Dev null将默默接受所有输入。

答案 1 :(得分:2)

关闭文件句柄

close $fh;

会使您对该文件句柄的所有prints失败。运行

no warnings 'closed';

禁止生成的所有警告消息(你做use warnings,对吧?)

答案 2 :(得分:1)

通过魔术,你可以创造一个神奇的手柄,操作总是成功。

perl -e'
   {
      package Handle::Dummy;
      use Tie::Handle qw( );
      use Symbol qw( gensym );
      our @ISA = qw( Tie::Handle );
      sub new { my $fh = gensym; tie *$fh, $_[0]; $fh }
      sub TIEHANDLE { bless(\my $dummy, $_[0]) }
      sub READ  { return 1; }
      sub WRITE { return 1; }
      sub CLOSE { return 1; }
   }

   my $fh = Handle::Dummy->new();   
   print($fh "abc\n") or die $!;
   close($fh) or die $!;
   print("ok\n");
'
ok

这避免了系统调用,但它用昂贵的Perl子例程调用替换它们。

简单地使用/dev/null更简单,更可靠 [1] 。它也可能更快。

  

打印标记为/dev/null可能已优化

没有。 Perl对/dev/null一无所知。

您认为系统调用的速度有多慢?这听起来不是优化的正确方法!

  1. 魔法文件句柄与系统文件句柄无关,因此无法传递给C库,它不会存在exec等。

答案 3 :(得分:-1)

您可以使用an anonymous, temporary file(约为perldoc页面的四分之一),就像这样;

#!/usr/bin/env perl
use strict;
use Getopt::Long;

my $fh;
my $need_log = 2;
print "Intitial need_log: $need_log\n";

GetOptions('flag!' => \$need_log);
print "After option processing, need_log: ", $need_log, "\n";

if ($need_log) {
  open($fh, '>', "log.txt") or die "Failed to open log: $!\n";
}
else {
  open($fh, '>', undef);
}

print $fh "Hello World... NOT\n";
exit 0;

以下是一些不同使用 - flag 选项的运行;

User@Ubuntu:~$ ls -l log.txt
ls: cannot access log.txt: No such file or directory
User@Ubuntu:~$ ./nf.pl
Intitial need_log: 2
After option processing, need_log: 2
User@Ubuntu:~$ cat log.txt
Hello World... NOT
User@Ubuntu:~$ rm log.txt
User@Ubuntu:~$
User@Ubuntu:~$
User@Ubuntu:~$ ./nf.pl --flag
Intitial need_log: 2
After option processing, need_log: 1
User@Ubuntu:~$ cat log.txt
Hello World... NOT
User@Ubuntu:~$ rm log.txt
User@Ubuntu:~$
User@Ubuntu:~$
User@Ubuntu:~$ ./nf.pl --noflag
Intitial need_log: 2
After option processing, need_log: 0
User@Ubuntu:~$ cat log.txt
cat: log.txt: No such file or directory
User@Ubuntu:~$

我已将$need_log变量初始化为' 2' ,以便我们可以判断它是否有' True&# 39; 作为flag选项存在的结果(在这种情况下,它将具有值 1 )或由于未提及标记选项而导致全部(在这种情况下,它将具有值 2 )。

指定&#39; - noflag&#39; 会触发包含&#39; undef&#39; 的else子句作为创建<的第三个参数em>匿名临时文件。这并不完全符合你根本不写的问题,但是如果文件是临时的并且你没有放入千兆字节,那么这就足够了。 / p>