Yes, I have it working using macros, but that ends up bloating my code a bit.
On Sun, Aug 23, 2009 at 5:30 PM, Timothy Pratley<timothyprat...@gmail.com> wrote: > > 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. > > > -- Howard M. Lewis Ship Creator of Apache Tapestry The source for Tapestry training, mentoring and support. Contact me to learn how I can get you up and productive in Tapestry fast! --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---