您好。我正在使用vertx,它非常有趣,但是对于事件总线通信,它需要大量的样板,甚至最糟糕的是,如果我需要更改某个函数名,我需要在4或5个地方更改它。
只需知道,我正在使用一个抽象来将vertx回调转换为channels..like
;;helper
(defn send [add msg]
(let [ch (chan 1)]
(eb/send add msg #(put! ch %))))
;;I wrap the event bus sender in a function for make a bit cleaner the code
(defn eb-get-cached-view [name id]
(send "render:get-cached-view" [name id])) ;;return chan[response]
(eb-get-cached-view "something" "here");;and finally I use it
;;in other verticle, I write the funcion
(defn get-cached-view [name id]
(...))
;;and enable an event bus listener pointing to that function
;; basically I receive a vector, pass it to my function, which return a channel, then I reply to the message with the response
(eb/on-message "render:get-cache-view" #(go (eb/reply (<! (apply get-cached-view %)))))正如您所看到的,这是很多样板,而且我担心每次更改函数名时,我都会错过在某个点更改它,而且我的代码会失败,我遵循使用我的命名空间的惯例的on消息参数后面跟着":“和函数名。
我在想比这更好的事情
(defbus blah
[name]
(str "hi! " name))这个宏构建函数blah,并为具有“呈现”命名空间的消息创建总线监听器(,我可以访问宏中的命名空间吗?是好方法吗?)
(eb/on-message "namespace:blah" #(go (eb/reply (<!(apply get-cached-view %))))) ;;apply is necessary because the messages are received inside a vctor以及用于发送消息的宏。
(<eb namespace:blah "john Smith") ;; could be a key like :namespace:blah too也不愿翻译成这样
(defn namespace:blah [message]
(let [ch (chan 1)]
(eb/send "namespace:blah" message #(put! ch %))))
(namespace:blah "john Smith")使用这些宏,我可以避免模板,更改回调以实现承诺,或者避免函数名称中的不一致。
这是个好方法吗?写这些宏是可能的,还是我忽略了某个点?.我对clojure有点陌生,我不知道它是否有可能,为什么它还不存在.
我很感激对我的代码的任何帮助或更正(我背诵了这段代码)
-“编辑1----------------------------------------------------------”
我写了这个宏(多亏了亚瑟).它比最后的宏简单一些,只用于演示
(defmacro defbus [bus-name args code]
`(let [fun# (fn ~args ~code)]
(println (str *ns* ":" ~bus-name))
(eb/on-message (str *ns* ":" ~bus-name) (fn [arg#] (apply fun# arg#)))))我认为,当我尝试使用它时,宏扩展是相当well...but的。
(defbus blah [a b] (str "just " a " " b))
java.lang.RuntimeException: Unable to resolve symbol: blah in this context似乎比我可以直接使用blah,但是一个simbol或string...Am,我遗漏了什么?(我是一个使用宏的新手,所有的例子都与我所需要的非常不同)谢谢!
发布于 2015-02-27 22:22:57
您可以在名称*ns*的任何地方访问命名空间表单--在这种情况下,如果宏使用正在调用的名称空间定义事件总线,而不是使用定义助手函数或宏的名称空间,则会非常方便。
user> (defmacro defbus [bus-name]
`(eb/on-message (str *ns* ":" ~bus-name) :dostuff))
#'user/defbus
user> (macroexpand-1 '(defbus foo))
(eb/on-message (clojure.core/str clojure.core/*ns* ":" foo) :dostuff)这个宏将返回调用on消息的代码,然后在调用者名称空间中计算它,其中ns被绑定到该名称空间,我假设这就是您想要的。
https://stackoverflow.com/questions/28774203
复制相似问题