Искусство программирования для Unix
Шрифт:
Инструментарий Qt является важным и видимым компонентом проекта KDE, старейшего из двух конкурирующих проектов с открытым исходным кодом по разработке GUI и интегрированного набора настольных приложений.
Реализация Qt на С++ демонстрирует преимущества ОО-языка программирования для инкапсуляции компонентов пользовательского интерфейса. В языке, поддерживающем объекты, видимая иерархия элементов управления интерфейса может быть четко выражена с помощью иерархии экземпляров классов в коде программы. Несмотря на то, что то же самое можно сымитировать в С с помощью явного преобразования через созданную вручную таблицу методов, код, написанный на С++, будет гораздо чище. Полезно сравнить его с известным своей
Исходный код и справочная документация по Qt доступна на сайте Trolltech <http://www.trolltech.com/>.
14.4.3. Shell
Первым (и долгое время единственным) переносимым интерпретируемым языком был 'Bourne shell' (sh) 7 версии Unix. В настоящий момент родоначальный Bourne shell в значительной степени вытеснили разновидности совместимого снизу вверх Korn Shell (ksh). Единственным наиболее важным из них является Bourne Again Shell (bash).
Существуют и согласованно используются несколько других видов shell, но как языки программирования они не столь значительны. Наиболее известным из них, вероятно, является С shell (csh), печально известный своей непригодностью для написания сценариев91.
Элементарные shell-программы чрезвычайно просты и естественны в написании.. Язык shell послужил началом Unix-традиции быстрого создания прототипов на интерпретируемых языках.
Я написал самую первую версию netnews в виде shell-сценария в 150 строк. Она имела несколько групп новостей и перекрестную рассылку. Группы новостей представляли собой каталоги, а перекрестная рассылка была реализована как множественные ссылки на статью. Программа была слишком медленной для реального использования, но ее гибкость позволяла бесконечно экспериментировать с конструкцией протокола.
Стивен М. Белловин.
Однако по мере увеличения своего размера, shell-программы часто становятся скорее узкоспециальными. Некоторые моменты синтаксиса shell (особенно правила использования кавычек и синтаксис операторов) могут сбить с толку. Данные недостатки, как правило, обусловлены компромиссами в той части конструкции shell, которая связана с языком программирования. Эти компромиссы были внесены, для того чтобы сохранить эффективность shell как интерактивного интерпретатора командной строки.
Программы описывают как "shell-программы" даже если они не написаны исключительно на shell, но в них интенсивно используются С-фильтры, такие как sort(1), и стандартные мини-языки обработки текста, такие как sed(1) или awk(1). Однако данный вид программирования в течение нескольких лет идет на убыль. В наши дни подобная сложная связующая логика обычно пишется на Perl или Python, a shell резервируется для простейших упаковщиков (для которых данные языки были бы чрезмерно сложными) и сценариев инициализации системы (которая не предполагает, что они доступны).
Базовое shell-программирование достаточно описано в любой вводной книге по Unix. "The Unix Programming Environment" [39] остается одним из лучших источников для программистов среднего и высокого класса. Реализации или клоны Korn shell представлены в каждой Unix-системе.
Сложные shell-сценарии часто имеют проблемы переносимости не столько из-за самой оболочки, а ввиду сделанных в них предположений о доступности той или иной программы в качестве компонента. Несмотря на то, что в отдельных случаях клоны bash и ksh доступны в операционных системах, отличных от Unix, shell-программы (практически) вообще невозможно перенести за пределы Unix.
В
завершение отметим, что лучшее качество shell — естественность и быстрота написания небольших сценариев. Худшей стороной shell является то, что крупные shell-сценарии зависят от множества вспомогательных команд, которые вовсе не обязательно идентично ведут себя и даже не всегда присутствуют на всех целевых машинах. Кроме того, анализировать зависимости в крупных shell-сценариях также непросто.Почти никогда не возникает необходимость компилировать или устанавливать shell, поскольку все Unix-системы и эмуляторы Unix поставляются с подобными оболочками. Стандартной оболочкой для Linux и других передовых вариантов Unix в настоящее время является bash.
14.4.3.1. Учебный пример: xmlto
xmlto — управляющий сценарий, который вызывает все команды, необходимые для представления какого-либо XML-DocBook-документа в виде HTML, PostScript, простого текста или любого другого доступного формата (более подробно DocBook рассматривается в главе 18). Сценарий xmlto написан в bash.
Детали вызова XSLT-процессора обрабатываются в xmlto с помощью соответствующей таблицы стилей, затем результаты передаются постпроцессору. Для HTML и XHTML вся обработка сводится к трансформации. Для получения простого текста XML также трансформируется в HTML, а затем передается постпроцессору — 1упх(1) в режиме -dump, который преобразовывает HTML в простой текст. Для получения PostScript XML трансформируется в XML FO (Formatting Objects — объекты форматирования), которые постпроцессор затем преобразовывает в TgX-макрос, DVI-формат посредством tex(1), а затем, наконец, в PostScript с помощью широко известного инструмента dvi2ps( 1).
xmlto состоит из одного интерфейсного shell-сценария. Он вызывает одну из нескольких подключаемых подпрограмм, каждая из которых названа по имени целевого формата. Каждая подключаемая подпрограмма представляет собой shell-сценарий. В зависимости от того как она вызвана, подключаемая подпрограмма либо предоставляет клиентской части таблицу стилей, либо вызывает соответствующий постпроцессор (или постпроцессоры) с различными заранее заданными аргументами.
Такая структура означает, что вся информация о заданном целевом формате находится в одном месте (соответствующем подключаемом сценарии), поэтому добавление новых целевых типов можно осуществить, не нарушая интерфейсного кода вообще.
Программа xmlto является хорошим примером shell-приложения среднего размера. Использование С или С++ не имело бы смысла, поскольку они неудобны для написания сценариев. Для такой программы можно было бы использовать любой из языков сценариев, описанных в данной главе; однако программа состоит только из простых команд управления без внутренних структур данных или сложной логики, поэтому достаточно использовать shell, так как это дает значительное преимущество — повсеместное распространение на целевых системах.
Теоретически данный сценарий можно было бы выполнить на любой системе, поддерживающей bash. Единственным ограничением является необходимость присутствия в системе одного из XSLT-процессоров, а также всех постпроцессоров. На практике маловероятна работа данного сценария во всех системах, кроме современных Unix-систем с открытым исходным кодом.
14.4.3.2. Учебный пример: Sorcery Linux