是否有可能重写'require'命令,以便它会尝试下载某个资源(如果它在本地计算机上未找到)。例如:在Clojure中重写'require'?
(require 'examples.introduction)
; if not found => download from the net
; (url: http://media.pragprog.com/titles/shcloj/code/examples/introduction.clj)
是否有可能重写'require'命令,以便它会尝试下载某个资源(如果它在本地计算机上未找到)。例如:在Clojure中重写'require'?
(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
将不会很有帮助,因为classpath注入在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
名称空间中实现的,而来自名称以clojure
开头的名称空间的Vars当前由编译器直接链接(这意味着在运行时不会执行实际的Var查找,因此重新绑定这些Vars对代码没有影响) 。
在ns
形式为您的命名空间中的(:refer-clojure :exclude [require])
防止require
从解析为clojure.core/require
,并让你免费在自己的名称空间定义名称的无功。如上所述,如果您键入完全限定的符号,则不会阻止可访问Var。clojure.core/require
Var。
其实,(附加类路径 “http://foo/bar/baz/src/ ”)或(附加类路径“ http://www.foo.com/bar.jar”),将允许需要远程的东西。
Michał的警告虽然适用:只用于此在repl的指责...
有趣。我在想,为了避免使用命名空间解决方法,可能会更好地使用不同的函数名称,如“enhanced-require”。 (我是一个总noob,所以纠正我,如果我说废话:)) – StackedCrooked 2010-04-25 19:47:18
相反,这似乎是一个更好的方式去做。不过,我必须指出,实际上,最好的方式是让Leiningen/Maven获得任何库依赖关系,并且像源代码随书一样,只需下载并手动下载...: - )并不是说它需要任何东西来写出一个可以自己完成的时髦需求。 – 2010-04-25 19:53:05