15.13 Наименование глобальных переменных библиотечных функций
Благодаря пути, по которому развивался язык awk, переменные этого языка или глобальные ( действующие во всей программе) или локальные ( используемы только конкретными функциями). Нет переменных промежуточного типа, подобных статическим переменным в Си.
Библиотечные функции часто нуждаются в глобальных переменных, которые они могут использовать, чтобы сохранить состояние информации между вызовами функции. Например, переменная .opti функции getopt (см, раздел 15.10 [Обработка параметров командной строки], стр., 186), и массив .tm.months, используемый функцией mktime (см. раздел 15.7 [Превращение даты в отметку времени], стр. 177). Такие переменные называются частными, поскольку их используют только функции из библиотеки.
Когда пишут библиотечную функцию, нужно стараться так выбрать имена для частных переменных, чтобы не было конфликтов с любыми другими переменными, используемыми другими библиотечными функциями или главной программой пользователя. Например, имя вроде `i' или `j' не является хорошим выбором, потому что пользовательские программы часто используют подобные имена для собственных целей.
В примерах программ, приведенных в этой главе, имена частных переменных начинаются с символа подчеркивания (`.'). Пользователи обычно не употребляют ведущих подчеркиваний в именах их переменных, так что такое соглашение сразу уменьшает шансы того, что это имя случайно встретится в пользовательской программе. Кроме того, некоторые из библиотечных функций используют префикс, который помогает указывать, что функция или группа функций используют эту переменную. Например, .tm.months в mktime (см. раздел 15.7 [Превращение дат в отметки времени], стр. 177), и .pw.byname в подпрограммах для пользовательских баз данных (см. раздел 15.11 [Чтение пользовательских баз данных], стр. 192). Мы рекомендуем пользоваться этим соглашением, поскольку оно еще больше уменьшает возможность случайных конфликтов в именах переменных. Заметим, что это соглашение можно использовать не только для имен переменных, но также и для частных имен функций.
Хотя я мог бы переписать все библиотечные подпрограммы с использованием этого соглашения, я намеренно не сделал этого, для того чтобы показать, как развивался мой собственный стиль awk-программирования и предоставить базис для настоящей дискуссии.
Как заключительная нота в наименовании переменных, если функция делает глобальные переменные доступными для использования в главной программе, хорошо начинать такие переменные с заглавной буквы. Например, переменные Opterr и Optind в функции getopt (см. раздел 15.10 [Обработка параметров командной строки], page 186). Ведущие заглавные буквы указывают, что переменные --- глобальные, а тот факт, что не все буквы заглавные, показывает, что это не встроенная переменная awk, подобная FS.
Также важно, чтобы все переменные в библиотечных функциях, которые не нуждаются в сохранении состояния, были фактически объявлены локальными. Если это не сделано, переменная может случайно использоваться в программе пользователя, что приведет к ошибке, которую очень трудно проследить.
function lib.func(x, y, l1, l2) -
... использует переменную some.var # some.var может быть локальной ...
# но это не очевидно с первого взгляда ""
Другое соглашение, обычное в объединении Tcl, состоит в использовании отдельного ассоциативного массива для запоминания значений, нужных для библиотечных функций или для "пакета." Это значительно уменьшает количество фактически используемых глобальных имен. Например, функции, описанные в разделе 15.11 [Чтение пользовательской базы данных], стр. 192, могут использовать PW.data["inited"], PW.data["total"], PW.data["count"] и PW.data["awklib"] вместо .pw.inited, .pw.awklib, .pw.total и .pw.count.
Предлагаемые в этом разделе соглашения есть только советы. От вас не требуется писать программы только так, мы только рекомендуем это.