Я пишу небольшое приложение, которое включает функцию смены пароля с валидаторами для качества пароля. В настоящее время валидаторы указаны на карте примерно так:
(def validations
{:min-length 6
:max-length 32})
Карта проверок определена в пространстве имен проверок, но позже я планирую переместить ее в пространство имен конфигурации. Мое решение использовать карту таким образом было сделать настройку прямо для непрограммистов.
В пространстве имен проверок есть несколько функций проверки, которые обычно принимают форму:
(defn min-length [n s]
{:req (str "be at least " n " characters long")
:pass? (>= (.length (or s "")) n)})
Так что с функцией выше (min-length 3 "clojure")
вернет {:req "be at least 3 characters long", :pass? true}
.
Я могу подтвердить пароль с помощью этой функции в пространстве имен проверки с помощью этой функции:
(defn validate-new-password [password]
(into {} (for [[k v] validations]
[k (eval (list (-> k name symbol) v password))])))
В результате получается что-то вроде:
>(validate-new-password "clojure")
{:min-length {:req "be at least 6 characters long", :pass? true},
:max-length {:req "be no longer than 32 characters long", :pass? true},
:min-digits {:req "have at least 1 digit", :pass? false},
:allow-whitespace {:req "not contain spaces or tabs", :pass? true},
:allow-dict-words {:req "not be a dictionary word", :pass? false}}
Каков наиболее практичный способ разрешения функций проверки, когда функция validate-new-password вызывается извне пространства имен проверки?
За последние недели я пробовал несколько подходов, но никогда не был доволен полученной формой (и ни один из них не сработал!).
Обычно я предполагаю, что вопрос «как символы разрешаются в пространстве имен: require'd при вызове функциями в этом пространстве имен?»
Меня также интересуют любые общие комментарии о моей реализации.