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

Reply via email to