2017-02-01 5 views
0

Я получаю странное поведение при поиске файлов с использованием glob. (я думаю, его предназначение, но я не хочу этого в моем случае)perl glob проверить, существует ли файл с префиксом

У меня есть 2 файла с именем aaa:bbb и aaa:ccc.

У меня есть код, чтобы узнать, существуют ли файлы с префиксом aaa:*. Я делаю это с помощью этого кода:

my $filelocation_special = "aaa"; 

if (glob($filelocation_special . ":*")) { 
    # file(s) exists! 
} 

Это работает. Однако, если я снова запустил тот же код еще два раза, glob возвращает undefined.

это мои доходы: (большую часть времени в любом случае)

print STDERR "glob: " . glob($filelocation_special . ":*") . "\n"; 

# 1 run: aaa:bbb 
# 2 run: aaa:ccc 
# 3 run: 

Что я могу сделать, чтобы сбросить glob всегда просто проверить, если файлы с этим префиксом существует?

Может быть, я должен использовать некоторые разные проверки вообще, но я не могу найти что-либо, что быстро, и просто проверяет, существуют ли файлы.

+0

Извините. Я обновил свой вопрос. –

+1

Если я копирую, если 3 раза, это работает для меня. http://stackoverflow.com/help/mcve – toolic

+0

Это 'CORE :: glob' или': bsd_glob' из http://perldoc.perl.org/File/Glob.html? – simbabque

ответ

3

if (glob(...)) является call to glob in scalar context.

В скалярном контексте GLOB перебирает таких имен файлов расширений, возвращая UNDEF когда список исчерпан.

Так каждый раз вы называете glob в скалярном контексте, с теми же аргументами, и из одной и тех же строк кода, вы получите другой результат, и в конечном итоге вы получите undef когда список файлов, которые соответствуют ваш аргумент исчерпан.

Чтобы получить выражение, «если есть файлы, соответствующие этому шаблону ...», вам нужно как-то использовать контекст списка.

@tmp = glob(pattern) 
if (@tmp) 

if (()=glob(pattern)) 

if (@{[glob(pattern)]}) 


Diversion: любой из них также работают (потому что @* являются действительными глобальные идентификаторы массивов для многих значений препинания *)

if (@@=glob(pattern)) 
if (@<=glob(pattern)) 
if (@:=glob(pattern)) 

, и они даже могут быть написаны как

if (@ <= glob(pattern)) 
if (@ := glob(pattern)) 

и еще несколько кандидатов для secret operators.

@@ = EXPR  like the goatse operator, returns a count of elements 
@ <= EXPR  in EXPR when EXPR is evaluated in list context; useful 
@ := EXPR  when EXPR in scalar context does not do this 
+0

Ничего себе. Это какой-то действительно странный код. Я попробовал. И он работал так, как я этого хотел. Благодаря! –

+0

Есть неплохая дискуссия о скалярном глобусе в [этот вопрос] (http://stackoverflow.com/questions/2633447/why-doesnt-perl-file-glob-work-outside-of-a-loop-in-scalar- контекст). – mob

+1

Использование символических идентификаторов, подобных этому, обескураживается, поскольку они зарезервированы для встроенных переменных Perl. Также очень неразумно писать код, используя неопределенные символические переменные с пробелами в необычных местах, так как большинство программистов на Perl не смогут быстро разобрать его. Очевидным способом проверки существования файлов, соответствующих шаблону 'glob', является' if (my @files = glob 'aaa: *') {...} ', где массив' @ files' определен только для длины блока 'if'. «секретные операторы» - это скорее инфантильные игрушки, а не действующие конструкции для использования в производственном программном обеспечении – Borodin

 Смежные вопросы

  • Нет связанных вопросов^_^