Опция командной строки -n преобразует код в нечто, эквивалентное
while ($ARGV = shift @ARGV) {
open ARGV, $ARGV;
LINE: while (defined($_ = <ARGV>)) {
$seen{$_} .= @ARGV;
print $_ if $seen{$_} =~ /10$/;
}
}
Пока первый файл читается, scalar @ARGV есть 1. Для каждой строки 1 будет добавлен в запись %seen.
Пока считывается второй файл, scalar @ARGV - 0. Итак, если строка была в файле 1 и в файле2, запись будет выглядеть как 1110000 (это было 3 × в файле1, 4 × в файле2).
Мы хотим только вывести общие строки ровно один раз. Мы делаем это, когда общая строка сначала отображается в файле2, поэтому $seen{$_} - 1110. Это выражается как регулярное выражение /10$/: строка 10 должна появиться в конце.
Ответ 2
@ARGV сдвигается при открытии первого файла. В скалярном контексте он теперь возвращает 1 (потому что он имеет один член, второй файл). Для каждой строки это 1 добавляется к показанному хешу. Когда второй файл открывается, @ARGV снова смещается и теперь пуст, поэтому возвращает 0 в скалярном контексте. /10$/ означает, что строка была видна в файле1, и теперь она впервые была замечена в файле2.