Happy to say that a little utility library of mine, clj-metasearch was released earlier this week.
This library allows you to search through all Clojure namespaces in the current classpath for vars which have metadata matching a predicate. This has a number of potential uses, such as automatically finding functions, or other types of vars that have metadata marking them as some kind of "plugin" for the application. You could do something like:
Which would scan the currently loaded namespaces only for any vars containing metadata with a
which had a "truthy" value.
find-vars returns a sequence of maps:
You can use
var-get on the
:var value to get the actual value found. I'll likely be changing this return value
format somewhat and possibly introducing a kind of "transform" function as an additional optional argument to
find-vars that can be used to transform these results as they are found so the return value is exactly in the format
If you wanted to scan all namespaces, including ones that have yet to be loaded:
The extra parameter will cause each namespace to be loaded via
require before it is checked. This can potentially
cause problems or warnings to be output. For example, if namespaces are loaded that redefine vars, or other namespaces
that can't be loaded in the current JVM version (
clojure.core.reducers is an example of this, it can't be loaded on
Java 6 without some extra library also being present).
When using the
:require-all-namespaces? parameter it's usually best to supply an extra predicate to limit the number
of Clojure namespaces that are checked (if this is at all possible for your use case):
Example: Automatic Compojure Route Discovery
So, I originally put this library together because I wanted to be able to automatically find Compojure routes and have them get added to the Ring handler routes vector without me needing to explicitly list them all out. This is admittedly quite a minor thing to need to do, but it has always seemed silly to me that adding routes to a Ring handler is a manual process in your typical Clojure web app.
Right now I just use a couple macros and a single function for this automatic Compojure route discovery:
register-restricted-routes macros are drop-in replacements for Compojure's
def-restricted-routes. Example use of
Would find all the Compojure routes defined with the
register-restricted-routes macros and
also append the routes in
app-routes to this list. You would then pass the returned list off to your Ring handler.