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
-~----------~----~----~----~------~----~------~--~---

Reply via email to