There is a ticket for metadata on functions: https://www.assembla.com/spaces/clojure/tickets/94-GC--Issue-90---%09-Support-metadata-on-fns So it seems this is a planned feature, but not implemented yet - due to "Requires dealing with the with-meta copying issues for closures".
But as you mentioned, the macro version should suffice for your case? (ns metatest (:use clojure.test)) (def cascade-type-to-virtual-folder {:view "view" :action "action" :willow "willow"}) (defmacro path-to-function "Calculates the path to a given view or action function. The result is a path string, relative to the context root. If the function defines :path meta-data, that it used, otherwise an appropriate path is constructed within the virtual /view or /action folder." [function] `(let [fn-meta# (meta (var ~function)) type# (get fn-meta# :cascade-type) folder# (get cascade-type-to-virtual-folder type#) fn-path# (get fn-meta# :path)] (println "function " ~function " meta" fn-meta#) (when (or (nil? type#) (nil? folder#)) (println "Function is neither a view function nor an action function.")) (cond ;; TODO: The user-supplied path may need some doctoring. It should not start with or end ;; with a slash. (not (nil? fn-path#)) fn-path# ;; Go from type to folder true (str folder# "/" (ns-name (fn-meta# :ns)) "/" (name (fn- meta# :name)))))) (defn valid-view-fn {:cascade-type :view} []) (defn valid-action-fn {:cascade-type :action} []) (defn pathed-action-fn {:cascade-type :action :path "do/something"} []) (defn pathed-view-fn {:cacade-type :view :path "show/something"} []) (defn unknown-type-fn {:cascade-type :willow}[]) (defn no-cascade-type-fn []) (println (path-to-function valid-view-fn)) On Aug 24, 1:41 am, Howard Lewis Ship <hls...@gmail.com> wrote: > I keep running in circles with meta data on functions. > > This is my current understanding: > > Meta data for the function's name symbol is merged with any meta data > provided as a map before the parameter decls. > > This combined meta-data is then applied to the Var that holds the function. > > However, it doesn't look like the function get the meta data. This is > extra odd, because the AFn constructor takes a meta data map (though > it throws UnsupportedOperationException if you attempt to use > (with-meta).) > > I'd like to say I'm just mistaken, but I see this is my code: > > (defn path-to-function > "Calculates the path to a given view or action function. The result > is a path string, > relative to the context root. If the function defines :path > meta-data, that it used, otherwise > an appropriate path is constructed within the virtual /view or > /action folder." > [function] > (let [fn-meta (meta function) > type (get fn-meta :cascade-type) > folder (get cascade-type-to-virtual-folder type) > fn-path (get fn-meta :path)] > (debug "function %s, meta %s" function (ppstring fn-meta)) > (fail-if (or (nil? type) (nil? folder)) > (format "Function %s is neither a view function nor an action function." > (qualified-function-name function))) > (cond > ;; TODO: The user-supplied path may need some doctoring. It > should not start with or end > ;; with a slash. > (not (nil? fn-path)) fn-path > > ;; Go from type to folder > > true (str folder "/" (ns-name (fn-meta :ns)) "/" (name (fn-meta > :name)))))) > > and tests: > > (defn valid-view-fn {:cascade-type :view} []) > (defn valid-action-fn {:cascade-type :action} []) > (defn pathed-action-fn {:cascade-type :action :path "do/something"} []) > (defn pathed-view-fn {:cacade-type :view :path "show/something"} []) > (defn unknown-type-fn {:cascade-type :willow}[]) > (defn no-cascade-type-fn []) > > (deftest test-path-to-function > (are (= (path-to-function _1) _2) > valid-view-fn "view/cascade.test-path-map/valid-view-fn" > valid-action-fn "action/cascade.test-path-map/valid-action-fn" > pathed-action-fn "do/something" > pathed-view-fn "show/something")) > > Execution: > > Testing cascade.test-path-map > [DEBUG] cascade.path-map function > cascade.test_path_map$valid_view_fn__...@eedabc, meta nil > > I can make my test work by passing #'valid-view-fn instead of valid-view-fn: > > Testing cascade.test-path-map > [DEBUG] cascade.path-map function > #'cascade.test-path-map/valid-view-fn, meta {:ns #<Namespace > cascade.test-path-map>, > :name valid-view-fn, > :file "cascade/test_path_map.clj", > :line 42, > :arglists ([]), > :cascade-type :view} > > But this isn't what I want. > > I think I can get the syntax I like using a macro, but I don't > understand why a Fn, which implements the IMeta interface (because it > extends from the Obj base class), doesn't have access to its own meta > data. This would be useful just for name, line, arglists, etc., not to > mention user-added meta data such as :cascade-type. > > My work around may be to use a macro to access the Var for the meta > data ... I just don't understand the reasoning behind the nil meta > data for functions. --~--~---------~--~----~------------~-------~--~----~ 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 Note that posts from new members are moderated - please be patient with your first post. 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 -~----------~----~----~----~------~----~------~--~---