Что такое _ (одно подчеркивание) в Perl без $или @?
У меня есть такой код:
if (!-d _ || !-o _ || ($vncUserDirUnderTmp && ($mode & 0777) != 0700)) {
raise Exception("$prog: Wrong type or access mode of $vncUserDir.\n")
}
Я мог бы найти информацию о @_
и $_
в Perl, но не о _
.
Что это означает в -d _
и -o _
здесь?
Ответы
Ответ 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, никакой специальной магии не произойдет.)