2010-09-19 88 views
5

Perl::Critic::Policy::InputOutput::ProhibitExplicitStdin为什么要在Perl中使用<ARGV>或<>代替<STDIN>?

引用Perl有一个有益魔法文件句柄名为* ARGV是检查命令行,如果有任何参数,打开并读取那些为文件。如果没有参数,* ARGV的行为与* STDIN相反。如果你想创建一个从STDIN读取的程序,这种行为几乎总是你想要的。这通常是写在以下两种等价形式之一:

while (<ARGV>) { 
    # ... do something with each input line ... 
} 
# or, equivalently: 
while (<>) { 
    # ... do something with each input line ... 
} 
  • 是它“只是一个约定”,还是有一些充分的理由不使用<STDIN>

我觉得<STDIN>让我的代码的意图不是使用<><ARGV>更加清晰。

我的代码的流程是这样的

my @inp = <STDIN>; 
my $len = $inp[0]; 

... 

for(my $i = 0; $i < ($len + 0); $i++) { 
    my @temp = split (' ', $inp[$i]); 
    ... 
} 

回答

5

这是因为使用<ARGV>将使用户要么指定文件从作为参数,或管道的东西读入标准输入,同时指定没有参数。如果使用<STDIN>,则只有管道可以工作。

当然,由您决定是否认为人们可以将文件指定为命令行参数,但这是很多程序支持的,因此可能值得考虑。

+0

感谢。如果这是唯一的原因,那么我觉得''更好。 – Lazer 2010-09-19 12:22:57

+1

@Lazer:这不是“更好”,它对你使用该程序的方式施加限制。为什么不必要地这样做? – Ether 2010-09-19 17:43:46

+0

Perl :: Critic是基于“Perl最佳实践”一书的,它简单地陈述:“避免使用* STDIN,除非你确实是这个意思。”给出的理由是上述答案的更长版本。如果你确实意味着只有STDIN会执行,则不会接受命令行参数 - 然后使用显式STDIN。 – jmanning2k 2010-09-20 20:06:39

6

你使用那个你想做的事。有关ARGV文件句柄的说明,请参见perlvarARGV也从您在命令行上指定的文件名读取。也许你想要那个功能,也许你不需要。

而且,你不必做Perl :: Critic所说的。许多这些政策是一小群人的意见。如果你只想明确地从STDIN读取,那就是你需要做的。撰写批评政策的人不在这里说明你需要做什么。提出这样的问题在没有其应用背景的情况下几乎毫无意义。一般规则仅仅是一般性的,在讨论具体案例时会被打破。

我不确定你为什么认为你的意图比STDIN更清楚,因为你没有告诉我们你的意图。代码几乎从来没有为自己说话,因为我们倾向于编码解决方案,而不是说明问题。解决方案可能不是正确的。

在你的情况,我觉得这个代码更加清晰,因为它是用Perl编写的,而不是的C语言你使用:)

chomp(my $length = <STDIN>); 

my $count = 0; 
while (<STDIN>) { 
    last if $count++ > $lines_to_read; 

    my @temp = split ' '; 
    ...; 
    } 
相关问题