По второму вопросу:
while (<FILE>) {
}
и
foreach (<FILE>) {
}
Имеют такое же функциональное поведение, включая настройку $_
. Разница в том, что while()
оценивает <FILE>
в скалярном контексте, а foreach()
оценивает <FILE>
в контексте списка. Рассмотрим разницу между:
$x = <FILE>;
и
@x = <FILE>;
В первом случае $x
получает первую строку FILE
, а во втором случае @x
получает весь файл. Каждая запись в @x
- это отдельная строка в FILE
.
Итак, если FILE
очень велико, вы тратите впустую память, теряя все сразу, используя foreach (<FILE>)
по сравнению с while (<FILE>)
. Это может или не может быть проблемой для вас.
Место, где это действительно важно, это если FILE
- дескриптор канала, как в:
open FILE, "some_shell_program|";
Теперь foreach(<FILE>)
должен ждать завершения some_shell_program
, прежде чем он сможет войти в цикл, в то время как while(<FILE>)
может считывать вывод some_shell_program
по одной строке за раз и выполнять параллельно some_shell_program
.
Тем не менее, поведение в отношении $_
остается неизменным между двумя формами.