2016-01-21 42 views
1

我正在使用Clojure库来尝试向我的应用程序中的任何函数添加行为。robert.hooke;或如何将元数据附加到Clojure中的函数

这里就是我想要做:

(require '[robert.hooke :as hook]) 

(defn new-behavior 
    [f & args] 
    (let [id "test"] 
    (println "The new behavior is to output the ID defined at the hook level: " id) 
    (apply f args))) 

(defn add-behavior! 
    [id task-var] 
    (hook/add-hook task-var new-behavior)) 

然后我想补充一个行为是这样的:

(defn foo [] (println "foo test")) 

(add-behavior! "foo-id" #'foo) 

我想做些什么能在这里做的就是以某种方式改变在add-behavior!函数中的vartask-var函数的元数据,然后从new-behavior函数访问新的元数据。我希望能够做这样的事情(注意,这不是明显的工作):

(defn new-behavior 
    [f & args] 
    (let [id (::behavior-id (meta f))] 
    (println "The new behavior is to output the ID defined at the hook level: " id) 
    (apply f args))) 

(defn add-behavior! 
    [id task-var] 
    (alter-meta! task-var assoc-in [::behavior-id] id) 
    (hook/add-hook task-var new-behavior)) 

(defn foo [] (println "foo test")) 

(add-behavior! "foo-id" #'foo) 

目前的方法是不行的,因为在add-behavior!它改变了var什么的元数据我我正在访问的new-behavior是函数的元数据,它是nil

所以,这导致了两个问题:

  1. 我怎么能访问关联到new-behaviorfunctionvar的元数据?
  2. 或者,我如何更改add-behavior中的varfunction的元数据?

回答

0

通过partial向var new-behavior提供var是否可以接受?

(defn new-behavior 
    [the-var f & args] 
    (let [id (::behavior-id (meta the-var))] 
    (println "The new behavior is to output the ID defined at the hook level: " id) 
    (apply f args))) 

(defn add-behavior! 
    [id task-var] 
    (alter-meta! task-var assoc-in [::behavior-id] id) 
    (hook/add-hook task-var (partial new-behavior task-var))) 

(defn foo [] (println "foo test")) 

(add-behavior! "foo-id" #'foo) 

不知道更多关于您试图解决的问题,很难判断这里是否有更好的设计。

+0

奇妙的是,这是可行的,因为参数约定只在'add-behavior!'和'new-behavior'之间。所以我一定会测试这个选项。我不知道“partial”,所以它是我工具箱中的一个新工具。这个想法是能够在我的应用程序中进行配置文件,内省,日志等任何功能,而无需更改代码的功能。所以这样的钩子是完美的,一旦你可以大胆他们:) – Neoasimov

+0

完全按照预期工作。谢谢! – Neoasimov

+0

顺便说一句,您可以通过匿名函数获得与“partial”相同的功能:'#(apply new-behavior task-var%&)' – gfredericks