Было бы возможно переопределить 'потребовать' команду так, чтобы это попыталось загрузить определенный ресурс, если это не было найдено на локальной машине. Например:
(require 'examples.introduction)
; if not found => download from the net
; (url: http://media.pragprog.com/titles/shcloj/code/examples/introduction.clj)
Вы можете переопределить функцию 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 [require ...] ...)
), не будет работать, поскольку require
обычно разрешает Var интернирован в пространстве имен clojure.core
, а переменные из пространств имен, имена которых начинаются с clojure
, в настоящее время напрямую связаны компилятором (это означает, что фактический поиск Var не выполняется во время выполнения, поэтому повторная привязка этих Вар не влияет на код).
(: refer-clojure: exclude [require])
в форме ns
для вашего пространства имен предотвращает преобразование require
в clojure.core / require
и позволяет вам определять Var с таким именем в вашем собственном пространстве имен. Как упоминалось выше, это не мешает clojure.core / require
Var быть доступным, если вы вводите полностью определенный символ.
На самом деле (add-classpath " http: // foo / bar / baz / src / ") или (add-classpath " http://www.foo.com/bar.jar "), разрешит запрашивать удаленные данные.
Предупреждения Михала действительно применимы: используйте это только для игрушек при ответе ...