Would it be possible to override the 'require' command so that it will try to download a certain resource if it was not found on the local machine. For example:
(require 开发者_Python百科'examples.introduction)
; if not found => download from the net
; (url: http://media.pragprog.com/titles/shcloj/code/examples/introduction.clj)
You could override the require
function and of course the overriden variant could download stuff if the namespace it was asked for is not available on the classpath. Overriding the way :require
works in (ns ...)
forms is, AFAIK, impossible for now due to the way in which ns
is handled.
Note that such a 'downloading require
' wouldn't be very helpful if you wanted to place new paths on the classpath (including new jars), as classpath injection doesn't work reliably in Clojure (due to JVM issues). There is clojure.core/add-classpath
... but it's been marked as deprecated since forever now, its use is strongly discouraged, there are no guarantees that it will work for you and this situation isn't likely to change anytime soon. On the other hand, if you wanted to put new source files in a directory which was already present on the classpath, then that should work fine.
In case you do want to play around with overriding require
, if you have a foo
namespace, you could do
(ns foo
(:refer-clojure :exclude [require])
; other stuff; any :requires here will work as usual!
)
Then define your own require, using clojure.core/require
when appropriate:
(defn require [ns-symbol]
(do-stuff-to-obtain-the-namespace))
clojure.contrib.find-namespaces
namespace might be helpful in finding out what's available on the classpath. (Or you could use the the-ns
function and see if it throws an exception after an initial attempt at requiring the namespace through clojure.core/require
.)
Note that the binding
approach which might come to mind first ((binding [require ...] ...)
) will not work, since require
normally resolves to a Var interned in the clojure.core
namespace and Vars from namespaces whose names start with clojure
are currently directly linked by the compiler (meaning no actual Var lookup is performed at runtime, so rebinding of those Vars has no effect on the code).
The (:refer-clojure :exclude [require])
in the ns
form for your namespace prevents require
from resolving to clojure.core/require
and leaves you free to define a Var of that name in your own namespace. As mentioned above, that doesn't prevent the clojure.core/require
Var from being accessible if you type out the fully qualified the symbol.
Actually, (add-classpath "http://foo/bar/baz/src/") or (add-classpath "http://www.foo.com/bar.jar"), will allow requiring remote stuff.
Michał's warnings do apply though: Only use this for toying at the repl ...
精彩评论