是否可以覆盖'require'命令,以便在本地计算机上找不到某个资源时尝试下载该命令.例如:
(require 'examples.introduction)
; if not found => download from the net
; (url: http://media.pragprog.com/titles/shcloj/code/examples/introduction.clj)
Run Code Online (Sandbox Code Playgroud)
您可以覆盖该require函数,当然,如果所要求的命名空间在类路径上不可用,则覆盖的变体可以下载内容。据我所知,由于:require处理方式的原因,覆盖表单中的工作方式目前是不可能的。(ns ...)ns
请注意,如果您想在类路径上放置新路径(包括新的 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!
)
Run Code Online (Sandbox Code Playgroud)
然后定义您自己的需求,clojure.core/require在适当的时候使用:
(defn require [ns-symbol]
(do-stuff-to-obtain-the-namespace))
Run Code Online (Sandbox Code Playgroud)
clojure.contrib.find-namespaces命名空间可能有助于找出类路径上可用的内容。(或者您可以使用该the-ns函数并查看它在首次尝试通过 请求命名空间后是否引发异常clojure.core/require。)
请注意,binding首先想到的方法 ( (binding [require ...] ...)) 不起作用,因为require通常会解析为clojure.core命名空间中驻留的 Var,并且名称开头的命名空间中的 Varclojure当前由编译器直接链接(这意味着在以下位置不执行实际的 Var 查找)运行时,因此重新绑定这些变量对代码没有影响)。
命名空间的形式会阻止(:refer-clojure :exclude [require])解析to并让您可以在自己的命名空间中自由定义该名称的 Var。如上所述,如果您键入完全限定的符号,这不会阻止 Var 被访问。nsrequireclojure.core/requireclojure.core/require