From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Date: Mon, 27 Jun 2005 16:15:07 +0400 From: Stanislav Ievlev To: devel@altlinux.org Message-ID: <20050627121507.GA15686@basalt.office.altlinux.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="OXfL5xGRrasGEqWY" Content-Disposition: inline Content-Transfer-Encoding: 8bit Cc: Subject: [devel] I: alterator internals - 5 X-BeenThere: devel@altlinux.ru X-Mailman-Version: 2.1.5 Precedence: list Reply-To: ALT Devel discussion list List-Id: ALT Devel discussion list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 27 Jun 2005 12:15:10 -0000 Archived-At: List-Archive: List-Post: --OXfL5xGRrasGEqWY Content-Type: text/plain; charset=koi8-r Content-Disposition: inline Content-Transfer-Encoding: 8bit Продолжение истории... 3. Первый модуль Мы уже узнали достаточно чтобы попробовать написать свой первый модуль для alterator. Так что не будем медлить с долгими рассказами, и сразу же приступим к делу. Я пока не буду давать лишних комментариев, и объяснять что и почему, просто смотрите как это сделать и всё ;) Если формат backend'a покажется вам несколько странным, то объясню - он был изначально рассчитан на существование в виде модуля для виртуальной файловой системы - admfs. Сейчас она не используется - а формат остался ... может в будущем мы вернёмся к этой идее, уж больно она красивая. Для того чтобы создать простейший модуль для alterator, надо: 1. написать низкоуровневую часть - backend, которая собственно и будет крутить ручки в системе 2. написать интерфейс Давайте сделаем модуль, который позволит выбирать пользователю локаль в системе. 3.1 Устройство backend. Интерфейс и backend будут обмениваться между собой посредством команд фиксированного формата: "<объект> <действия>". Объект принято именовать так же как и объекты в файловой системе, то есть последовательность слов, разделённых символом '/'. Например: /users/root /network/interfaces/eth0 Первая часть имени совпадает с именем файла бакенда. Например /users/root - файл backend, называется users /network/interfaces/eth0 - файл backend называется network Оставшаяся часть имени передаётся backend и он дальше сам разбирается с тем что с ней делать. Действия есть последовательность атрибутов со значениями, один атрибут имеет особое значение, зовут его action. action - собственно означает какое действие мы можем предпринять над объектов. Возможные значения action: read - прочитать атрибуты объекта write - изменить некоторые атрибуты объекта list - получить список объектов которые данный содержит (аналогично ls в каталоге) new - создать объект delete - удалить объект Атрибут action всегда должен присутствовать в команде. Например: /users/test action=new uid=506 gecos="Some User" (создать пользователя тест с UID 506 и комментарием "Some User") /network/interfaces/eth0 action="read" (считать параметры интерфейса, например ip-адрес,шлюз etc.) Этот язык общения со времён первого alterator носит странное имя WOO. В нашем случае мы имеем следующие объекты: /i18n/current - текущее значение локали /i18n/available - установленные в системе локали ... /i18n/available/Russian locale for Russia - например одна из локалей в системе. Как можно догадаться, i18n - это будет имя нашего файла - backend'a. /i18n/current будет иметь следующие атрибуты: stdname - стандартное имя локали без кодировки, например "ru_RU" title - описательное имя локали, например "Russian locale for Russia" charmap - кодировка, например "KOI8-R" stdname.charmap - даёт стандартное системное имя, которое обычно содержится в переменной LANG, в нашем случае это ru_RU.KOI8-R. Можно было бы сделать один атрибут lang, но удобнее держать отдельно кодировку. Чтобы считать текущее значение, команда следующая: /i18n/current action=read Чтобы записать новое значение переменной LANG, команда следующая: /i18n/current action=write lang=ru_RU.KOI8-R Как видите атрибуты на чтение и запись не обязаны совпадать. Может это не совсем идеологически верно, зато удобно. 3.1.2 Пишем backend. С языком общения мы вроде как разобрались, теперь собственно формат backend. backend - это обычное приложение, написанное на произвольном языке программирования, который откликается на внешние раздражители следующим образом: *(action=read)* backend -r объект - выдать на stdout, атрибуты и их значения в формате: атрибут1:значение1 атрибут2:значение2 .... (соответственно имя атрибута не должно содержать двоеточия - это не очень сильное ограничение) объект - это хвост имени объекта, с отрезанным именем backend. Так "a/b/c/d" - урежется до "b/c/d". Например: (для woo-команды: /i18n/current action=read) $ ./i18n -r current stdname:ru_RU title:Russian locale for Russia charmap:KOI8-R $ ./i18n -r "available/Russian locale for Russia" stdname:ru_RU charmaps:CP1251,IBM866,ISO-8859-5,KOI8-R,UTF-8 *(action=list)* backend -l объект - выдать на stdout список подобъектов в формате "имя[пробел][r|d]" где d ставится рядом с объектом, содержащим другие объекты, а r - рядом с обычным объектом. Например: (для woo-команд: /i18n action=list и /i18n/available action=list) $ ./i18n -l / available d current r $ ./i18n -l available Russian locale for Russia r Russian locale for Ukraine r *(action=write,new)* backend -w объект - принять с stdin параметры в виде "атрибут:значение" и записать их в объект. Например: (для woo-команды: /i18n/current action=write lang=ru_RU.CP1251) $echo "lang:ru_RU.CP1251"| ./i18n -w current Отдельной команды для action=new нет, backend сам в состоянии догадаться, делать ему новый объект или модифицировать имеющийся. *(action=delete)* backend -d объект - удалить указанный объект Ну вот собственно и весь формат backend. Пример скрипта на shell, который всё это реализует приложен к письму. Думаю что вы легко сможете написать и свою версию, возможно даже более правильную и корректную ;) 3.2 Опять про Scheme: Локальные переменные Проведём небольшое усовершенствование своих познаний по Scheme. В Scheme в отличие от Common Lisp применяется привычный подход к понятию локальности (так называемый "Lexical Scope" против "Dynamic Scope" в Common Lisp): * Переменные определённые внутри некоторой функции видны во всех функциях, определённых внутри данной, но не видны вне её. (define a 3) (define (f) (define b 4) (define (g) (write b)) ; мы видим эту переменную так как g сама определена внутри f (g) (write a) ; мы видим эту переменную ибо она в охватывающем окружении (write b)) ; это наша локальная переменная (write b) ; ошибка a - определена внутри f и не видна на вышестоящем уровне. * Локальные переменные затеняют глобальные: (define a 3) (define (f) (define a 4) (write a)) (f) ; будет напечатано 4, а не 3, так как локальная переменная затенила глобальную. Параметры у многоаргументных функций, суть локальные переменные со всеми вытекающими последствиями: (define x 4) (define (f x) (write x)) (f 5) ; будет напечатано 5, а не 4 ибо x - локальная переменная в функции f. -- Продолжение следует ... --OXfL5xGRrasGEqWY Content-Type: application/x-bzip2 Content-Disposition: attachment; filename="i18n.bz2" Content-Transfer-Encoding: base64 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 --OXfL5xGRrasGEqWY--