How to pass arguments to decorators? #2500
-
I need to use a set of decorators that take arguments. I've tried this: (defn [(partial decorator "foo")] bar ... } But it doesn't seem to work. Any ideas? I could do this with |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 9 replies
-
You just call the function with arguments, same as before, and as in Python.
Can you be more specific? |
Beta Was this translation helpful? Give feedback.
-
I think I've finally got it, but it seems overly contrived: (defn tracer [func #* args]
(fn [#* args]
(do (print #* args)
(func #* args))))
(defn [tracer] test [x]
(print x)
(import functools [partial])
(defn tracer2 [prefix func #* args]
(fn [#* args]
(do (print prefix #* args)
(func #* args))))
(defn [(partial tracer2 ">")] test2 [x]
(print x)) This works, but I've scoured the documentation and tests and they do not provide good enough hints as to the best way to create and use decorators with arguments in "modern" Hy, so any pointers would be welcome (and yes, I need to both use arguments for existing decorators and export others out to Python).
|
Beta Was this translation helpful? Give feedback.
-
The order of arguments means interop is fiddly. I’m unwrapping older decorators I had written (that worked flawlessly either way) and coming across this time and time again. (Also, I don’t see keyword arguments as a solution for this) I can sort of make it work, but wish there was proper documentation (and written tests) for it that accounted for Python interop both ways. |
Beta Was this translation helpful? Give feedback.
-
Well, just to give an idea of what I'm currently doing, part of the code I'm "porting" back to Hy is stuff like this decorator, which was used in several HTTP routes like this: (with-decorator
(handle-get (+ *page-route-base* "/<pagename:path>"))
(report-processing-time)
(http-caching "pagename" "text/html" 3600)
(ttl-cache 30)
(render-view "wiki")
(defn wiki-page [pagename]
(if (in (.lower pagename) *redirects*) ... Due to the instability of earlier Hy releases, seven years ago I rewrote that in Python 3 like so (with minor changes since some of the tracing and caching had to allow for live runtime value updates): @get(PAGE_ROUTE_BASE + "/<pagename:path>")
@report_processing_time(STATS_ADDRESS, STATS_PORT)
@http_caching("pagename", "text/html", ASSET_HTTP_EXPIRY)
@lru_cache(10)
@view("wiki")
def wiki_page(pagename): Right now I'm trying to, in parallel, get both my public project and other, similar services working on "modern" Hy, hence my looking for better examples. My non-public projects have to use similar decorators (some of them with async frameworks, which is a minor difference), but those have to be shared with Python code that I'm not going to rewrite. |
Beta Was this translation helpful? Give feedback.
So you'd now write that as:
except you should rename
get
or it will be shadowed by the core macro of the same name. Straightforward enough, no? Am I missing something?