是否可以覆盖'require'命令,以便在本地计算机上找不到某个资源时尝试下载该资源。例如:
(require 'examples.introduction)
; if not found => download from the net
; (url: http://media.pragprog.com/titles/shcloj/code/examples/introduction.clj)
答案 0 :(得分:4)
您可以覆盖require
函数,当然,如果要求的命名空间在类路径中不可用,则覆盖变量可以下载内容。由于:require
的处理方式,覆盖(ns ...)
在ns
表单中工作的方式是AFAIK,现在是不可能的。
请注意,如果您想在类路径(包括新的jar)上放置新路径,那么'下载require
'将不会非常有用,因为类路径注入在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
通常会解析为clojure.core
命名空间中的Var并且名称以clojure
开头的名称空间的变量当前由编译器直接链接(意味着在运行时不执行实际的Var查找,因此重新绑定这些变量对代码没有影响)。
您的命名空间的(:refer-clojure :exclude [require])
表单中的ns
会阻止require
解析为clojure.core/require
,并让您自由在您自己的命名空间中定义该名称的Var。如上所述,如果您输入完全限定符号,则不会阻止clojure.core/require
Var被访问。
答案 1 :(得分:1)
实际上,(add-classpath“http://foo/bar/baz/src/”)或(add-classpath“http://www.foo.com/bar.jar”),将允许需要远程资料。
然而,Michał的警告确实适用:只能用这个来代替... ...