Подтвердить что ты не робот

Что такое _ (одно подчеркивание) в Perl без $или @?

У меня есть такой код:

if (!-d _ || !-o _ || ($vncUserDirUnderTmp && ($mode & 0777) != 0700)) {
    raise Exception("$prog: Wrong type or access mode of $vncUserDir.\n")
}

Я мог бы найти информацию о @_ и $_ в Perl, но не о _. Что это означает в -d _ и -o _ здесь?

4b9b3361

Ответ 1

При использовании с filetest (-X) используется stat структура предыдущего теста файла

Если какой-либо из тестов файла (или оператора stat или lstat) задается специальная дескриптор файла, состоящий из одиночной подчеркивания, то структура stat предыдущего теста файла (или оператор stat) используется, сохраняя системный вызов.
...
Пример:

stat($filename);  
print "Readable\n" if -r _;  
print "Writable\n" if -w _;
...

Итак, в вашем примере !-d _ проверяется, не является ли файл последним stat -ed не каталогом.

Обновить  

Необычный _ действительно является typeglob *_, но с операторами, ожидающими дескриптор файла, * может быть опущен, например <*STDIN> может быть записан как <STDIN>. Он находится в таблице символов

print *{$main::{_}}{IO}, "\n";   # -->  IO::Handle=IO(0x2311970)

В одном вкладыше *_ устанавливается только после того, как сделаны вызовы stat и _.

Ответ 2

При вызове одного из операторов проверки файлов (-f, -d, -s и т.д.) Perl фактически выполняет вызов функции stat операционной системы. Функция stat возвращает структуру, полную всех видов интересной информации о файле, о котором идет речь, но каждый из операторов проверки файлов рассматривает только одно из полей этой структуры (это файл? Это каталог? How большой это?)

Общеизвестно, что вам может понадобиться узнать больше о том, что одна часть информации о файле (это файл? могу ли я его прочитать? могу ли я его выполнить?) Наивный способ записи:

if (-f $file and -r $file and -x $file)

Но это вызывает три вызова stat - каждый из них смотрит только на одно из полей из структуры. Чтобы смягчить это, Perl является умным и кэширует результаты последнего вызова stat. Он кэшируется против специальной дескриптор файла _. Таким образом, более эффективный способ записи одного и того же кода:

if (-f $file and -r _ and -x _)

Это вызывает только один вызов stat.

С Perl 5.10 вы также можете использовать "стековые проверки файлов" и написать этот код как:

if (-x -r -f $file) # Note reversed order of operators

Обновление: perldoc говорит об операторах сложенными файлами.

Как и Perl 5.10.0, как форма чисто синтаксического сахара, вы можете стековый файл, таким образом, что -f -w -x $fileэквивалентно "-x $file && -w _ && -f _. (Это только фантазия синтаксис: если вы используете возвращаемое значение -f $file в качестве аргумента другому оператору filetest, никакой специальной магии не произойдет.)