Ниже приведены несколько советов, которые сделают ваш код более идиоматическим:
- Специальная переменная
$.
уже содержит текущий номер строки, поэтому вы, вероятно, можете избавиться от $lctr
.
- Являются ли пустые строки действительно ошибками, или вы можете их игнорировать?
- Раздвиньте список, возвращенный из
split
, и дайте названия кусочкам.
- Пусть Perl сделает открытие с «оператором алмазов» :
Нулевой дескриптор файла <>
является особенным: его можно использовать для эмуляции поведения sed
и awk
. Ввод из <>
поступает либо из стандартного ввода, либо из каждого файла, указанного в командной строке. Вот как это работает: при первом вычислении <>
проверяется массив @ARGV
, а если он пуст, $ARGV[0]
устанавливается на "-"
, что при открытии дает стандартный ввод. Затем массив @ARGV
обрабатывается как список имен файлов. Петля
while (<>) {
... # code for each line
}
эквивалентен следующему Perl-подобному псевдокоду:
unshift(@ARGV, '-') unless @ARGV;
while ($ARGV = shift) {
open(ARGV, $ARGV);
while (<ARGV>) {
... # code for each line
}
}
за исключением того, что это не так громоздко, и на самом деле будет работать.
Скажем, ваш ввод находится в файле с именем input
и содержит
Campbell's soup,0.50
Mac & Cheese,0.25
Затем с
#! /usr/bin/perl
use warnings;
use strict;
die "Usage: $0 coupon-file\n" unless @ARGV == 1;
while (<>) {
chomp;
my($product,$discount) = split /,/;
next unless defined $product && defined $discount;
print "$product => $discount\n";
}
, который мы запускаем, как показано ниже в Unix:
$ ./coupons input
Campbell's soup => 0.50
Mac & Cheese => 0.25