До выхода 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";
}