Сгруппированная проверка файлов

До выхода Perl 5.10, если вы хотели одновременно проверить несколько атрибутов файла, это приходилось делать по отдельности (даже при том, что дескриптор _ избавлял вас от части работы). Допустим, мы хотим узнать, доступен ли файл для чтения и записи одновременно. Для этого необходимо сначала выполнить проверку на чтение, а затем проверку на запись:

if( -r $file and -w _ ) {
print "The file is both readable and writable!\n";
}

Конечно, проверки было бы удобнее выполнить одновременно. Perl 5.10 позволяет последовательно сгруппировать операторы проверки перед именем файла: use 5.010;

if( -w -r $file ) {
print "The file is both readable and writable!\n";
}

Пример почти не отличается от предыдущего, изменился только синтаксис. Хотя на первый взгляд кажется, что порядок проверки изменился, в действительности Perl начинает с оператора, находящегося ближе к имени. Обычно это несущественно. Сгруппированные проверки файлов особенно удобны в сложных ситуациях. Допустим, требуется найти все каталоги, доступные для чтения, записи и исполнения, владельцем которых является текущий пользователь. Для этого понадобится лишь правильный набор файловых проверок:

use 5.010;
if( -r -w -x -o -d $file ) {
print "My directory is readable, writable, and executable!\n";
}

Группировка не подходит для проверок с возвращаемыми значениями, отличными от true и false, которые нам хотелось бы использовать в сравнениях.


Казалось бы, следующий фрагмент кода сначала проверяет, что элемент является каталогом, а затем – что его размер менее 512 байт, но на самом деле это не так:

use 5.010;
if( -s -d $file < 512) { # WRONG! DON'T DO THIS
print "The directory is less than 512 bytes!\n";
}

Чтобы понять, что происходит, достаточно записать сгруппированные проверки файлов в предыдущем варианте записи. Результат комбинации проверок становится аргументом для сравнения:

if( ( -d $file and -s _ ) < 512 ) {
print "The directory is less than 512 bytes!\n";
}

Когда –d возвращает false, Perl сравнивает полученное значение false с 512. Результат сравнения оказывается истинным, потому что false интерпретируется как 0, а это меньше 512. Чтобы не создавать путаницы и помочь программистам сопровождения, которые придут после нас, достаточно разделить проверку на две части:

if( -d $file and -s _ < 512 ) {
print "The directory is less than 512 bytes!\n";
}

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела Perl на эту тему:
Операторы проверки файлов
Поразрядные операторы
Проверка нескольких атрибутов одного файла
Работа с битовыми строками
Функции stat и lstat