Reputation: 11
I am working on a clojure DSL for guitar tablature and I want to allow users to write plugins by defining a function called apply-clojure-plugin
in a known file location (say plugins.clj
).
I've tried:
load
the file and calling the function (resulting in "Unable to find symbol: apply-clojure-function". declare
to avoid the above issue (resulting in "Attempting to call unbound fn")I'm guessing it is some sort of namespace issue but I can't quite make out how to use ns-resolve
here (if it's even necessary).
EDIT: I ended up solving this with resolve
. The issue was that apply-clojure-plugin
isn't defined at compile time (since it is defined in the file), so an error is thrown during compilation. Calling (resolve 'apply-clojure-plugin)
works fine.
Upvotes: 1
Views: 228
Reputation: 20194
You either want (load "plugins")
(if the directory containing the file is on the classpath), or (load-file "path/to/plugins.clj")
to load from a known file path relative to the execution (or absolute path).
If the file contains no ns
form, you will be able to access its definitions directly. Otherwise, you will need to know which ns the file defines, and you can use alias
to map that namespace into your own:
;; make a new namespace for demonstration purposes
:user=> (ns foo)
nil
;; a definition in the other namespace
:foo=> (def bar "hello")
#'foo/bar
;; switch back to the original namespace
:foo=> (in-ns 'user)
#object[clojure.lang.Namespace 0x14a50707 "user"]
;; our definition is not visible
:user=> (resolve 'bar)
nil
;; but it is visible based on the fully qualified namespace
+user=> (resolve 'foo/bar)
#'foo/bar
;; using alias, we can make a convenient shorthand
+user=> (alias 'f 'foo)
nil
+user=> f/bar
"hello"
Upvotes: 2