Если я хочу найти размер массива, созданный <>
, почему это не работает?Размер массива, генерируемого <>?
print "Number of .DOC and .PDF files is: " scalar(<*.PDF *.DOC>);
Вместо этого указывается имя первого файла соответствия.
Если я хочу найти размер массива, созданный <>
, почему это не работает?Размер массива, генерируемого <>?
print "Number of .DOC and .PDF files is: " scalar(<*.PDF *.DOC>);
Вместо этого указывается имя первого файла соответствия.
Начнем с выяснения некоторых из ваших заблуждений.
glob
[1] никогда не возвращает массив. Операторы не возвращают массивы [2]; они возвращают скаляры. Иногда нет, иногда один, иногда много.
scalar
влияет на операторов, а не на значения, которые они возвращают. В частности, scalar
заставляет оператор внутри оцениваться в скалярном контексте.
Как на оператора влияет контекст, зависит от каждого отдельного оператора. Единственная константа состоит в том, что они должны возвращать ровно один скаляр в скалярном контексте. Существует много variety в том, что они предпочитают возвращать в скалярном контексте.
В скалярном контексте glob
действует итератор, возвращая следующий пункт он вернулся бы в контексте списка или undef
сигнализировать нет никаких дополнительных значений для возврата.
Решение:
Памяти эффективного решения:
my $num_files = 0;
++$num_files while <*.PDF *.DOC>;
print "Number of .DOC and .PDF files is: $num_files\n";
Более быстрое решение:
my @qfns = <*.PDF *.DOC>;
print "Number of .DOC and .PDF files is: " . @qfns . "\n";
встраиваемая версия выше:
print "Number of .DOC and .PDF files is: " . @{[ <*.PDF *.DOC> ]} . "\n";
Еще быстрее, менее расточительным, но более продвинутое решение:
print "Number of .DOC and .PDF files is: " . (() = <*.PDF *.DOC>) . "\n";
list assignment operator в скалярном контексте возвращает количество скаляров, возвращенных его РИТ.
Уборщик/очиститель?
my $num_files =() = <*.PDF *.DOC>;
print "Number of .DOC and .PDF files is: $num_files\n";
<*.PDF *.DOC>
это ярлык для glob(qq<*.PDF *.DOC>)
для @a
в определенных ситуациях За исключением (в том числе \@a
, @a = LIST
и массива манипуляторов, как push @a, LIST
).
Я бы использовал конкатенацию вместо '0 +' для принудительного применения скалярного контекста - например 'print 'Число файлов .DOC и .PDF:. (() = <*.PDF *.DOC>); ' –
@Dave Cross, Это то, что я тоже буду использовать, и так как я не придерживаюсь того, что использовал OP в любом случае, я обновил свой ответ – ikegami
@ user2864740 Как превратить список в массив в том же самом выражении? – CJ7
О, я был так не прав: см. Http://perldoc.perl.org/perlfunc.html#glob-EXPR «В * скалярном контексте *, glob выполняет итерацию через такое расширение имени файла ..» – user2864740