Анализатор для синтаксиса конфигурационного файла fetchmail является довольно сложным. Фактически он написан с использованием программ уасс и lex, двух классических инструментов Unix для создания кода синтаксического анализатора на языке С. Вначале разработчикам показалось, что для того чтобы с помощью fetchmailconf можно было редактировать существующие конфигурационные файлы, понадобится воспроизвести тот же сложный синтаксический анализатор в языке реализации fetchmailconf — Python.

Такая тактика выглядела бесперспективной. Даже если не принимать во внимание объем необходимой дублирующей работы, очень трудно быть уверенным в том, что два синтаксических анализатора, написанных на двух различных языках, допускают использование одной и той же грамматики. Обеспечить в дальнейшем их синхронизацию по мере развития конфигурационного языка будет чрезвычайно сложно. Данный подход нарушал бы правило SPOT, описанное в главе 4.

На какое-то время автор был поставлен в тупик данной проблемой. Разрешило ее интуитивное понимание того, что программа fetchmailconf может использовать собственный синтаксический анализатор fetchmail в качестве фильтра. В результате в fetchmail был добавлен параметр --conf igdurap, который позволял бы анализировать файл . fetchmailrc и отправлять результаты на стандартный вывод в формате РуЛоп-инициализатора. Для приведенного выше файла результаты выглядели бы приблизительно так, как показано в примере 9.2 (для экономии места некоторые данные, не связанные с примером, опущены). ^

Основное препятствие было преодолено. Интерпретатор Python мог затем оценить вывод fetchmail - - conf igdump и прочесть доступную для fetchmailconf конфигурацию как значение переменой "fetchmail".

Однако описанное препятствие было не последним. Было действительно необходимо не только предоставить fetchmail существующую конфигурацию, но превратить ее в связанное дерево действующих объектов. В данном дереве было бы 3 вида объектов: Configuration (объект верхнего уровня, представляющий всю конфигурацию), Site (представляющий один из серверов для опроса) и User (представляющий пользовательские данные, связанные с узлом). Файл в примере описывает 3 объекта Site, каждый из которых связан с одним пользовательским объектом.

Данные 3 класса объектов уже существовали в fetchmailconf. Каждый из них имел метод, который заставлял его выводить на экран GUI-панель редактирования для модификации своего экземпляра данных. Последняя проблема сводилась к некоторому преобразованию статических данных в Python-инициализаторе в действующие объекты.

'port':0, 'timeout':300, 'dns69:TRUE, "aka":None,

'users': [ {

"remote":"esr", "password":"masked_two", 1localnames':["esr"], 'fetchall':FALSE, 'keep':FALSE, 'flush':FALSE, "mda":None, 'limit':0, 1 warnings 1:3600,

}

1

} /

]

}

Пример 9.3. Код метакласса copy_instance def copy_instance(toclass, fromdict):

# Make a class object of given type from a conformant dictionary.

class_sig = toclass._diet_.keysO; class_sig. sort ()

dict_keys = fromdict.keys(); dict_keys.sort() common = set_intersection(class_sig, dict_keys) if 'typemap' in class_sig:

class_sig.remove(1typemap') if tuple(class_sig) != tuple(dict_keys): print "Conformability error"

# print "Class signature: " + "class_sig"

# print "Dictionary keys: " + ~dict_keys" print "Not matched in class signature: "+ \

"set_diff(class_sig, common)" print "Not matched in dictionary keys: "+ \

"set_diff(dict_keys, common)~

sys.exit(1) else:

for x in dict_keys:

setattr(toclass, x, fromdict[x])

Большую часть в примере представляет код контроля ошибок, учитывая возможность того, что члены класса и генерация отчета - -conf igdump выпали из синхронизации. Такая проверка гарантирует, что в случае возникновения сбой в коде будет обнаружен на ранней стадии, т.е. реализуется правило исправности. Главной частью кода являются две последние строки, которые устанавливают атрибуты в классе из соответствующих членов в словаре. Данные строки эквивалентны следующим строкам.

Перейти на страницу:

Похожие книги