Cool ! And by encapsulating this Voodoo code : (try (load "optional/cl-format") (catch Exception exc (when-not (re-find #"com/infolace/format__init" (str exc)) (throw exc))))
into a proper function named e.g. load-optional, you have then a small library (clojure.contrib.optional ?) in its own (with you defoptional macro) for optional behaviour :-) Regards, -- Laurent 2009/3/19 Meikel Brandmeyer <m...@kotka.de> > Dear Clojurians, > > I found the following procedure quite useful when > including Tom Faulhaber's cl-format in VimClojure. > > I didn't want to depend on it, so I decided to provide > the functionality optionally: if the cl-format.jar is > available use it, otherwise use some sensible default. > > The following layout is used by Chouser in clojure.contrib > but should deserve some more spotlight. > > To include the functionality I started with providing > some facade which also implements the defaults > > > (defn pretty-print > "Print the given form in a pretty way. If Tom Faulhaber's pretty printer > is > not installed simply defaults prn." > [form] > (prn form)) > > (defn pretty-print-code > "Print the given form in a pretty way. If Tom Faulhaber's pretty printer > is > not installed simply defaults prn. Uses the *code-dispatch* formatting." > [form] > (prn form)) > > > These functions are pretty straight forward. They > provide the interface used in VimClojure and default > to prn. > > Now we have to load the cl-format library. The problem > is, that if the library is not available this will throw an > exception at compile time. So wrapping the require > in try will not help. Here comes Chouser's trick: put the > require in another file and load this file. Using this > technique we can simply catch the Exception, check > with some Voodoo heuristic whether it was because > of the missing jar and re-throw otherwise. > > > (try > (load "optional/cl-format") > (catch Exception exc > (when-not (re-find #"com/infolace/format__init" (str exc)) > (throw exc)))) > > > In the optional/cl-format.clj file, we finally interface to > the optional library. We require the library and replace > the facade functions we defined before. > > > (require '[com.infolace.format :as cl-format]) > > (defoptional pretty-print > [form] > (cl-format/pprint form)) > > (defoptional pretty-print-code > [form] > (cl-format/with-pprint-dispatch cl-format/*code-dispatch* > (cl-format/pprint form))) > > > To save some work I defined a small helper macro, > which transfers the docstring from the default > implementation to the re-definition. > > (defmacro defoptional > [sym args & body] > `(let [docstring# (:doc (meta (var ~sym)))] > (defn ~sym ~args ~...@body) > (alter-meta! (var ~sym) assoc :doc docstring#))) > > > Now we have a completely optional dependency > on an external library. In case it's there, it will be > used. Otherwise the system falls back transparently > to the default implementation. > > Maybe you find this useful. > > Sincerely > Meikel > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---