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