В первой строке у вас есть проблема приоритета:
open F, $ARGV[0] || die $!;
совпадает с
open F, ($ARGV[0] || die $!);
, что означает, что die
выполняется, если имя файла равно false, а не если open
не удается. Вы хотели сказать
open(F, $ARGV[0]) || die $!;
или
open F, $ARGV[0] or die $!;
Кроме того, вы должны использовать форму с тремя аргументами open, если $ARGV[0]
содержит символы, которые что-то значат для open
.
open F, '<', $ARGV[0] or die $!;
На другой ноте разделение на /\s/
означает, что вы получаете «слово» между последовательными пробельными символами. Вы, вероятно, имели в виду /\s+/
, или, как подсказал амфетахин, /\W+/
, в зависимости от того, как вы хотите определить «слово».
Это все еще оставляет проблему пустого «слова», которое вы получаете, если строка начинается с пробела. Вы можете разделить на ' '
, чтобы подавить это (это особый случай), или вы можете сначала обрезать начальные пробелы, или вставить grep { length $_ }
, чтобы отсеять пустые "слова", или отказаться от split
и использовать другой метод для считая слова.
Обработка строки за строкой вместо чтения всего файла также была бы хорошим улучшением, но это не так важно, как у первых двух элементов.