Вы можете переопределить функцию require
и, конечно, переопределенный вариант может загрузить материал, если запрошенное пространство имен недоступно в пути к классам. Переопределение способа работы :require
в (ns ...)
формах, AFAIK, пока невозможно из-за способа обработки ns
.
Обратите внимание, что такая «загрузка require
» не будет очень полезной, если вы хотите разместить новые пути в пути к классам (включая новые jar-файлы), поскольку внедрение пути к классам не работает надежно в Clojure (из-за проблем с JVM ). Там есть clojure.core/add-classpath
... но он помечен как устаревший, так как навсегда, его использование настоятельно не рекомендуется, нет никаких гарантий, что он будет работать для вас, и эта ситуация вряд ли изменится в любое время скоро. С другой стороны, если вы хотите поместить новые исходные файлы в каталог, который уже присутствует в пути к классам, это должно работать нормально.
Если вы хотите поиграть с переопределением require
, если у вас есть пространство имен foo
, вы можете сделать
(ns foo
(:refer-clojure :exclude [require])
; other stuff; any :requires here will work as usual!
)
Затем определите свое собственное требование, используя clojure.core/require
, когда это необходимо:
(defn require [ns-symbol]
(do-stuff-to-obtain-the-namespace))
clojure.contrib.find-namespaces
Пространство имен может быть полезно для определения того, что доступно на пути к классам. (Или вы можете использовать функцию the-ns
и посмотреть, генерирует ли она исключение после первоначальной попытки запросить пространство имен через clojure.core/require
.)
Обратите внимание, что подход binding
, который может прийти в голову первым ((binding [require ...] ...)
), не будет работать, так как require
обычно разрешает Var, интернированный в пространстве имен clojure.core
, и Vars из пространств имен, имена которых начинаются с clojure
в настоящее время напрямую связаны компилятором (что означает, что в реальном времени поиск Var не выполняется, поэтому повторное связывание этих Vars не влияет на код).
(:refer-clojure :exclude [require])
в форме ns
для вашего пространства имен препятствует разрешению require
в clojure.core/require
и позволяет вам определять переменную с этим именем в вашем собственном пространстве имен. Как упомянуто выше, это не препятствует тому, чтобы clojure.core/require
Var был доступен, если вы вводите полностью квалифицированный символ.