Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should I use <ARGV> or <> instead of <STDIN> in Perl?

Quoting from Perl::Critic::Policy::InputOutput::ProhibitExplicitStdin

Perl has a useful magic filehandle called *ARGV that checks the command line and if there are any arguments, opens and reads those as files. If there are no arguments, *ARGV behaves like *STDIN instead. This behavior is almost always what you want if you want to create a program that reads from STDIN. This is often written in one of the following two equivalent forms:

while (<ARGV>) {
  # ... do something with each input line ...
}
# or, equivalently:
while (<>) {
  # ... do something with each input line ...
}
  • Is it "just a convention" or are there some solid reasons not to use <STDIN> ?

I feel <STDIN> makes my code's intentions more clear than using <> or <ARGV>.

The flow of my code is like this

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

...

for(my $i = 0; $i < ($len + 0); $i++) {
    my @temp = split (' ', $inp[$i]);
    ...
}
like image 959
Lazer Avatar asked Sep 19 '10 12:09

Lazer


1 Answers

You use the one that does what you want to do. See perlvar for an explanation of the ARGV filehandle. ARGV also reads from filenames you specify on the command line. Maybe you want that feature, maybe you don't.

And, you don't have to do what Perl::Critic says. Many of those policies are the opinions of a small group of people. If you only want to read from STDIN explicitly, that's what you need to do. The people writing the Critic policies aren't there to state what you need to do. Asking any question like this is mostly pointless without the context of its application. General rules are merely general, and break down when talking about specific cases.

I'm not sure why you think your intent is clearer with STDIN because you didn't tell us your intent. Code almost never speaks for itself because we tend to code the solution instead of stating the problem. The solution might not be the right one.

In your case, I think this code is more clear because it's written in Perl instead of the C dialect you're using :)

 chomp( my $length = <STDIN> );

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

     my @temp = split ' ';
     ...;
     }
like image 143
brian d foy Avatar answered Sep 27 '22 23:09

brian d foy