Теперь вы умеете определять базовое имя файла. Это полезно, но довольно часто возникает обратная задача: объединить его с именем каталога для получения полного имени файла. Например, в следующем фрагменте требуется прибавить префикс к базовому имени файла в полном имени вида /home/rootbeer/ice-2.1.txt:
use File::Basename;
print "Please enter a filename: ";
chomp(my $old_name = <STDIN>);
my $dirname = dirname $old_name;
my $basename = basename $old_name;
$basename =~ s/^/not/; # Добавление префикса к базовому имени
my $new_name = "$dirname/$basename";
rename($old_name, $new_name)
or warn "Can't rename '$old_name' to '$new_name': $!";
Видите, в чем проблема? Мы снова неявно предполагаем, что имена файлов соответствуют правилам UNIX, и используем косую черту для отделения имени каталога от базового имени. К счастью, Perl содержит готовый модуль для выполнения подобных операций. Модуль File::Spec предназначен для манипуляций с файловыми спецификациями, которые определяют имена файлов, каталогов и других объектов файловой системы. Как и File::Basename, этот модуль распознает файловую систему, в которой он работает, и автоматически выбирает нужный набор правил. Но, в отличие от File::Basename, модуль File::Spec является объектно-ориентированным (часто сокращается до ОО) модулем.
Если вы еще не заразились лихорадкой объектно-ориентированного программирования, пусть вас это не беспокоит. Разбираетесь в объектах – хорошо; вы сможете использовать ОО-модули. Не разбираетесь в объектах – тоже не страшно. Просто введите символические имена так, как мы вам покажем, и все будет прекрасно работать. Из документации File::Spec мы узнаем, что для решения нашей задачи необходимо использовать метод с именем catfile. Что такое метод? Просто разновидность функции (в том, что касается наших практических целей). Отличительная особенность методов заключается в том, что методы File::Spec всегда вызываются по полным именам:
use File::Spec;
.
. # Получить значения $dirname и $basename, как было сделано выше
.
my $new_name = File::Spec->catfile($dirname, $basename);
rename($old_name, $new_name)
or warn "Can't rename '$old_name' to '$new_name': $!";
Полное имя метода образуется из имени модуля (в этом контексте он называется классом), маленькой стрелки (->) и короткого имени метода. Очень важно использовать в записи именно маленькую стрелку, а не двойное двоеточие. Так как метод вызывается по полному имени, какие символические имена импортирует этот модуль? Никаких. Для ОО-модулей это нормально, поэтому вам не придется беспокоиться о возможных конфликтах между именами пользовательской функции и многочисленных методов File::Spec. Стоит ли использовать такие модули? Как обычно, решайте сами. Если вы уверены, что ваша программа всегда будет запускаться только на компьютерах с системой UNIX, а также в том, что хорошо знаете правила выбора имен файлов в UNIX1, возможно, вы предпочтете жестко закодировать свои предположения в программах. Однако модули предоставляют простой способ повысить надежность ваших программ, а также улучшить их портируемость без всяких дополнительных затрат.