Поиск

Обшие сведения о переносимости программ

Переносимость — это одно из основных преимуществ Perl, благодаря которому он и завоевал столь широкую популярность- Интерпретатор Perl гарантирует, что программа практически без изменений будет работать одинаково на любой из поддерживаемых компьютерных платформ (VMS, UNIX, Macintosh или DOS). Если в программе используются средства взаимодействия с операционной системой, такие как операции ввода/вывода, интерпретатор Perl пытается самостоятельно выполнить всю черновую работу и скрыть от программиста детали, обеспечивая при этом работоспособность кода. Однако в некоторых редких случаях требуется вмешательство программиста.

На 16-м занятии, "Сообщество Реrl, мы обсудим более подробно причины столь высокой переносимости программ на Perl.

На этом занятии мы уже не раз отмечали, что некоторые участки программ будут работать только в Windows и DOS, а другие — только в UNIX. Поэтому при написании программы вы должны учитывать тип операционной системы, на которой ее предполагается запускать. Это типичный пример машинно-зависимого программирования. При таком подходе требуется создать отдельные версии программ для каждой из операционных систем, например для Windows и UNIX. Наличие нескольких версий программы создает проблемы при разработке версии программы для третьей операционной системы, например MacOS 9.

Однако сказанное выше вовсе не означает, что профаммы на Perl, написанные для одной компьютерной платформы, например Windows NT, не будут работать на другой, например UNIX. Более того, чаще всего именно так и происходит — профам-мист работает в одной системе, а пользователи профаммы в другой. У некоторых пользователей даже складывается такое впечатление, что, поскольку интерпретатор Perl создан для большинства современных компьютерных платформ, выполнение программы в среде Windows NT ничем не отличается от среды UNIX. Переносимые профаммы имеет смысл создавать только в том случае, если они предназначены для работы на различных компьютерных платформах, как, например, Web-серверы и вспомогательные профаммы для них.

Учтите, что создание различных версий одной и той же профаммы, предназначенных для работы на всех возможных компьютерных платформах и во всех возможных ситуациях, — занятие очень хлопотное, непродуктивное и малоприятное. Ниже приведено несколько правил, выполнение которых гарантирует, что ваша профамма без изменений (или с незначительными изменениями) будет работать на любой платформе.

  • Всегда включайте режим выдачи предупреждений и используйте директиву use strict. Это позволит гарантировать, что ваш код будет корректно выполняться различными интерпретаторами Perl и что в профамме не будет фубых ошибок, о которых может предупредить компилятор.
  • Всегда проверяйте коды возврата после вызова системных функций. Например, при открытии файла используйте конструкцию open 11 die. Никогда не используйте оператор open сам по себе. Проверка кодов возврата позволяет выявить ошибки при переносе профамм с одного сервера на другой, а не только от одной платформы на другую.
  • Выводите краткие, но понятные сообщения об ошибках.
  • По возможности отдавайте приоритет встроенным функциям Perl перед функцией system и помещением вызова внешней профаммы в обратные кавычки.
  • Создавайте для всех системно зависимых операций (ввод/вывод, управление процессами и др.) соответствующие функции на Perl, которые будут играть роль оболочки. Не забудьте также проверить, что используемые вами средства реализованы в текущей операционной системе.

С первыми двумя рекомендациями вы уже должны быть хорошо знакомы. Во всех примерах этой книги анализируется код возврата после выполнения критичных функций, а начиная с 8-го занятия, "Функции", во всех больших примерах используется директива use strict и режим выдачи предупреждений.

С третьей рекомендацией о выводе понятных сообщений об ошибках трудно не согласиться. В самом деле, что может быть понятнее сообщений, приведенных ниже?

Очевидно, что последняя строка наиболее информативна. И даже если с момента написания программы пройдет достаточно много времени, вы всегда сможете определить место в программе (файл myscript.pl, строка 24), где произошла ошибка, и причину (не найден файл Foofile.txt) сбоя. Такая подробная информация поможет быстро устранить проблему. При написании программы не жалейте нескольких минут времени на создание хороших, информативных сообщений об ошибке. В будущем оно окупится сторицей.

Четвертая рекомендация означает, что везде, где только возможно, нужно использовать встроенные средства Perl. Например, для получения списка файлов каталога проще всего воспользоваться оператором наподобие $dir='dir' Однако он не будет работать на платформах, отличных от Windows. Поэтому лучше воспользоваться конструкцией <*> либо набором функций opendir/readdir/closedir (что предпочтительнее). При таком подходе ваша программа будет работать на любой платформе.

Как быть с отличиями?

Последняя рекомендация по написанию переносимых программ, рассмотренная в предыдущем разделе, требует небольшого пояснения на примерах. Напомним, что речь идет об использовании функций-оболочек для системно зависимых вызовов.

При написании программ на Perl не стоит забывать, что рано или поздно настанет момент, когда их придется запускать в другой операционной системе или на компьютере другого типа. А вдруг вы создадите нечто наподобие Web-сервера amazon.com, и ваш IBM PC не будет справляться с нахлынувшим потоком посетителей? Тогда вам придется перенести свой сервер на более мощный компьютер под управлением Windows NT или UNIX, или даже поместить его в кластер, состоящий из 10000 серверов UNIX на базе Sun Enterprise. Или другой более реалистичный пример. Предположим, что вы пользуетесь некоторым CGI-сценарием и решили поменять Web-провайдера, поскольку новый провайдер предоставляет более широкий набор услуг. Подобная ситуация случается сплошь и рядом и не требует особых комментариев.

Итак, как же программа сможет определить, на какой платформе она выполняется, и учесть отличия между Windows и UNIX? Все очень просто. В Perl предусмотрена специальная переменная $Л0 (знак доллара, за которым следуют символ вставки и прописная буква О), содержащая имя архитектуры компьютерной платформы, на которой выполняется программа. Например, в среде Windows и DOS ей присвоена строка MSWin32. В UNIX с помощью данной переменной можно определить тип операционной системы: linux, aix, Solaris, freebsd и т.д.

Ниже перечислено несколько типичных системно зависимых задач, которые часто приходится решать в пользовательских программах.

  • Поиск какой-либо информации, относящейся к конфигурации операционной системы.
  • Работа с диском и структурой каталогов.
  • Использование системных служб, например отправка электронной почты.

В качестве примера рассмотрим программу, с помощью которой можно легко оп-ределить количество свободного дискового пространства в системе. Она будет полезна в случае, если один из пользователей захочет загрузить из Internet какой-либо файл и перед загрузкой проверить, поместится ли он на локальном диске. Фрагмент программы на Perl, оценивающий в системе Windows количество свободного дискового пространства для устройства, на котором находится текущий каталог, выглядит так:

В этом фрагменте кода выбирается последняя строка листинга, полученного с помощью команды dir и помещенного в массив @dir. Далее с помощью регулярных выражений из этой строки выделяются числа и запятые, расположенные перед фразой bytes free. И, наконец, с помощью еше одного регулярного выражения из числа удаляются запятые, которые служат в качестве разделителей тысяч. В результате в переменной $free будет находиться размер свободного места на диске в байтах. Рассмотренный нами пример прекрасно работает в системе Windows. Для UNIX следует воспользоваться таким фрагментом программы:

Обратите внимание на отличие этого фрагмента кода от предыдущего. Для определения объема свободного пространства жесткого диска в системе Windows использовалась команда dir, а в UNIX — команда df -к .. Последняя строка, выводимая командой df -к ., разбивается на части, после чего извлекается содержимое четвертого (по счету) поля и присваивается переменной $free. Однако следует учитывать тот факт, что в различных системах UNIX выводимые командой df данные имеют разный формат (отличается количество полей) или поля расположены в другом порядке. Поэтому, если вы столкнетесь с такой проблемой, внесите необходимые коррективы в программу на Perl.

Итак, мы создали две программы для двух операционных систем Windows и UNIX, выполняющих одни и те же действия, — определение объема свободного пространства на диске. Теперь давайте объединим их в одну универсальную программу, которая будет работать и в Windows, и в UNIX.

Теперь наша универсальная программа включает версии для DOS/Windows и Linux. Если кто-то попытается запустить ее в другой операционной системе, будет выведено соответствующее предупреждение и программа корректно завершит свою работу. Теперь практически вся работа по написанию переносимой программы завершена. Осталось только оформить ее в виде подпрограммы. Тогда все ее внутренние переменные будут локальными, и при необходимости любой программист сможет легко воспользоваться созданной вами подпрограммой.

Теперь, когда вам понадобится определить, сколько места осталось на диске, вызовите функцию freespace(), и она вернет нужное значение. Если же эта функция будет вызвана в той операционной системе, которая ею не поддерживается, на экране появится сообщение об ошибке. Исправить подобную ситуацию довольно просто — добавьте еше один блок elsif в условный оператор if.