是否有可能重寫'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