Переопределение 'требует' в Clojure?

Было бы возможно переопределить 'потребовать' команду так, чтобы это попыталось загрузить определенный ресурс, если это не было найдено на локальной машине. Например:

(require 'examples.introduction) 
; if not found => download from the net
;   (url: http://media.pragprog.com/titles/shcloj/code/examples/introduction.clj)
5
задан StackedCrooked 25 April 2010 в 18:39
поделиться

2 ответа

Вы можете переопределить функцию 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 быть доступным, если вы вводите полностью определенный символ.

4
ответ дан 14 December 2019 в 19:06
поделиться

На самом деле (add-classpath " http: // foo / bar / baz / src / ") или (add-classpath " http://www.foo.com/bar.jar "), разрешит запрашивать удаленные данные.

Предупреждения Михала действительно применимы: используйте это только для игрушек при ответе ...

1
ответ дан 14 December 2019 в 19:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: