2010-07-23 4 views
2

Я пишу библиотеку Clojure, и мне интересно, что лучше всего подходит для настройки параметров конфигурации библиотеки.Как установить параметры конфигурации в библиотеке clojure?

Многие библиотеки (например, в clojure-contrib) используют глобальный параметр уровня, например *buffer-size*, который пользователь может установить, позвонив по телефону set!. Но для меня это не лучший способ создать глобальное состояние, и есть вероятность столкновения имен.

Другой способ - передать параметры в каждом вызове функции, который зависит от них. Если есть много параметров, тогда их можно использовать вместо передачи отдельных.

В качестве примера предположим, что я пишу библиотеку кеша.

Используя первый подход у меня есть глобальные параметры, такие как *cache-size*, *expiry-time*, *cache-dir* и т.д. Пользователь set! с этим (или нет, и пусть они будут по умолчанию) и вызывают функцию, как (set-in-cache id obj) и (get-from-cache id).

Используя второй подход, пользователь сначала создать карту параметров и передает его на каждый звонок

(def cache-parameters {:cache-size 1000 
         :expiry-time: 1440 
         :cache-dir "c:\\cache"}) 
(set-in-cache cache-parameters id obj) 
(get-from-cache cache-parameters id) 

Итак, какой способ является предпочтительным способом в Clojure и почему?

ответ

3

На самом деле вы можете не set! вещи, как c.c.io «s *buffer-size* если вы установите поток локального связывания их с binding, with-bindings и т.д. Там просто несколько Варс, для которых резьба локального крепления устанавливаются ниже уровня Clojure машин, такие как *warn-on-reflection* и *read-eval*, что делает их set! -доступными на верхнем уровне; определяемые пользователем Vars не являются set! -able на верхнем уровне. Корневое связывание Var может быть изменено, например, alter-var-root, intern, def, .bindRoot ..., но это следует использовать экономно.

Что касается перезаписываемых Vars против явных параметров, то часть вопроса: переход с явными параметрами почти всегда в порядке и обычно предпочтительнее только из-за повышенной ремонтопригодности функций, которые четко отображают все части данных, от которых они зависят. При этом, если некоторая часть конфигурации, вероятно, будет установлена ​​один раз, а затем будет использоваться практически каждый вызов функции в приложении/библиотеке после этого, это может сделать для более чистого кода, чтобы определить Earmuffed Var, хорошо документировать его и поместить конфигурацию в нем (и это может быть одним из редких случаев, когда изменение привязки корня Var за пределами формы, которая определяет, может быть в порядке).

Подводя итог, используйте свое мнение, если вы не уверены - ошибаетесь на стороне передачи явного параметра.

+0

Это последний бит * точно * что я сделал в clj-github и gotmilk. Удивительно знать, что я, возможно, сделал что-то правильно! – Rayne

+0

'он может сделать для более здравого кода, чтобы определить earmuffed Var ...' Можете ли вы привести пример? –

+0

@Rayne: ;-) @ abhin4v: Фактически '* buffer-size *', который вы упоминаете в вопросе, является хорошим примером использования Var для «разумного умолчания», который иногда может быть отскок по коду клиента. Что касается перекоса корневого значения Var, Congomongo (библиотека Clojure MongoDB) использует 'alter-var-root' в Var, который называется' * mongo-config * '(цель которого, как следует из названия). –