- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Искусство программирования для Unix - Реймонд Эрик Стивен
Шрифт:
Интервал:
Закладка:
setattr(toclass, x, fromdict[x])
Если разрабатываемый код настолько же прост, то весьма вероятно, что он верен. В примере 9.4 приведен код, вызывающий данный метакласс.
Ключевым моментом в данном коде является то, что он проходит 3 уровня инициализатора (конфигурация/сервер/пользователь), устанавливая корректные объекты каждого уровня в списки, содержащиеся в следующем объекте более высокого уровня. Поскольку метакласс copy_instance управляется данными и является полностью общим, его можно использовать во всех 3 уровнях для 3 различных типов объектов.
Данный пример — пример новой школы. Язык Python был создан гораздо позднее 1990 года. Однако пример отражает идеи, которые возвращаются к Unix-традициям 1969 года. Если бы размышления над Unix-программированием, практикуемым предшественниками, не научили бы автора "конструктивной лени" — настаивая на повторном использовании кода и отказе от написания дублирующегося связующего кода в соответствии с правилом SPOT — он мог бы "удариться" в программирование синтаксического анализатора на языке Python. Главное понимание того, что сама программа fetchmail могла бы превратиться в синтаксический анализатор конфигурации fetchmailconf возможно, никогда бы не пришло.
Пример 9.4. Вызывающий контекст для copy_instance
# Сложная часть - инициализация объектов из глобального класса configuration'.
# "Configuration1 - верхний уровень объектного дерева,
# который планируется изменить Configuration = Controls() copy_instance(Configuration, configuration) Configuration.servers = U;
for server in configuration['servers']: Newsite = Server() copy_instance(Newsite, server) Configuration.servers.append(Newsite) Newsite.users = [] ,-for user in server['users1]: Newuser = User() copy_instance(Newuser, user) Newsite.users.append(Newuser)
Другое понимание (того, что метакласс copy_instance может быть общим) происходит из Unix-традиции старательного поиска способов избежать кодирования вручную. Но особенно, Unix-программисты привыкли к написанию спецификаций для генерации синтаксических анализаторов для обработки языков разметки. Это скоро привело к предположению, что остальная часть работы может быть выполнена путем некоторого общего обхода дерева конфигурационной структуры. Для четкого разрешения задачи проектирования необходимо было два отдельных (один над другим) этапа создания программы, управляемой данными.
Интуитивное понимание подобное описанному может быть необыкновенно действенным. Рассматриваемый код был написан в течение приблизительно 90 минут, был работоспособен при первом запуске и с тех пор в течение многих лет оставался стабильным (единственный сбой произошел при обработке исключительной ситуации в присутствии действительного перекоса версий). Данный код содержит менее 40 строк и великолепно прост. Не существует способа, при котором примитивный подход полного создания второго синтаксического анализатора мог бы привести к созданию такого же удобства сопровождения, такой же надежности или компактности. Повторное использование кода, упрощение, обобщение, ортогональность — Дзэн операционной системы Unix в действии.
В главе 10 рассматривается синтаксис файла конфигурации fetchmail в качестве примера стандартного shell-подобного метаформата для конфигурационных файлов. В главе 14 fetchmailconf используется как пример, демонстрирующий мощность языка Python в быстрой разработке GUI-интерфейсов.
9.2. Генерация специального кода
Операционная система Unix оснащена несколькими мощными генераторами кода специального назначения, предназначенного для таких целей, как создание лексических анализаторов (tokenizers) и синтаксических анализаторов; они рассматриваются в главе 15. Однако существуют более простые, легковесные виды генераторов кода, которые можно использовать для облегчения работы программиста и не требуют знания теории компиляторов или написания процедурной логики (подверженной ошибкам).
Ниже приводится два иллюстративных учебных примера.
9.2.1. Учебный пример: генерация кода для ascii-дисплеев
Запущенная без аргументов программа ascii генерирует экран справочной информации по использованию, подобный распечатке, приведенной в примере 9.5.
Данный экран достаточно тщательно спроектирован, чтобы уместиться в 23 строки и 79 колонок, поэтому он помещается в терминальном окне 24x80.
Таблицу можно было бы создавать во время выполнения, т.е. на лету. Подгонка десятичных и шестнадцатеричных столбцов была бы достаточно простой. Однако существует достаточно необычных, делающих код крайне неудобным, случаев от перенесения строк таблицы в нужных местах до вывода таких неотображаемых символов, как NUL, вместо обычных символов. Более того, столбцы понадобилось бы неравномерно заполнять пробелами, чтобы заставить таблицу уместиться в 79 колонках. Но любой Unix-программист автоматически выражал бы таблицу как блок данных, прежде чем обнаружил бы данные проблемы.
Самым примитивным способом создания справочного экрана было бы помещение каждой строки в С-инициализатор в исходном коде ascii. с, а затем заставить код, проходящий через инициализатор, выписывать строки. Проблема такого метода заключается в том, что дополнительные данные в формате С-инициализатора (завершающие разделители строк, строковые кавычки, запятые) удлиняли бы строки более 79 символов. Это привело бы к переносу строк и усложнило бы преобразование внешнего вида кода к внешнему виду вывода, что, в свою очередь, усложнило бы редактирование справочного дисплея, который и без этого сложно было уместить в экран на 24x80 растровых ячеек.
Более сложный метод использования режима вставки строк в препроцессоре ANSI С приводит к другому варианту той же проблемы. По существу, любой способ явного включения в код справочного экрана задействовал бы пунктуацию в начале и конце строки, для которой не было места70. А копирование на экран таблицы из файла во время выполнения выглядело ненадежно. В конце концов, файл мог быть утерян.
Пример 9.5. Справка по использованию программы ascii
Usage: ascii [-dxohv] [-t] [char-alias...]
-t = one-line output -d = Decimal table -o = octal table -x = hex table -h = This help screen -v = version information Prints all aliases of an ASCII character. Args may be chars, С -escapes, English names, '"-escapes, ASCII mnemonics, or numerics in decimal/octal/hex.
Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex Dec Hex
0
00
NUL
16
10
DLE
32
20
48
30
0
64
40
®
80
50
P
96
60
112
70
P
1
01
SOH
17
11
DC1
33
21
I
49
31
1
65
41
A
81
51
Q
97
61
a
113
71
q
2
02
STX
18
12
DC2
34
22
ii
50
32
2
66
42
В
82
52
R
98
62
b
114
72
r