2015-09-11 58 views
0

我目前正在爲我在clojure中編寫的掃雷遊戲開發一個簡單的事件調度程序。如何唯一標識一個給定的clojure函數?

作爲起點我想到具有這樣的:

(def receivers (atom {})) 

隨着該附加一個給定的功能,以事件的特定地圖每個事件採用一組嵌套的,例如一個寄存器的功能{:do-sth#{func1 func2}}

據我所知,只要你再給函數名稱空間添加一個函數,它就會有不同的身份,這當然有道理,但讓我的方法失敗。

有沒有一種方法來唯一標識可能作爲參數傳入的函數?否則,我將不得不爲每個我希望儘可能避免的函數提供一個唯一的ID。

UPDATE

與clyfe建議去,我結束了以下第一種方法:

(def receivers (atom {})) 

(defn register 
    [event wrapped-function] 
    (if 
    (var? wrapped-function)  
    (swap! receivers 
      #(assoc %1 %2 (conj (or (get %1 %2) #{}) %3)) 
      event 
      wrapped-function) 
    (throw (IllegalStateException. 
      "wrapperd function must be a var")))) 


(defn bar 
    [] 
    "bar") 


(register :foo #'bar) 
+0

「只要你再添加一個函數到名稱步調「是由於代碼重新加載,這是讓你的問題? – clyfe

+0

是的,可能沒有「現實生活中的問題」,但我目前使用的是lighttable,一旦我運行我的東西,它會在原子保持原樣時再次添加函數。 – u6f6o

+0

我想過爲函數添加一些元數據,並在它不存在的情況下拋出異常。但對我來說看起來像一個骯髒的解決方法 – u6f6o

回答

1

如果問題是由於代碼重裝,你可以存儲功能的封閉變種在集合{:ev #{#'f1 #'f2}}中,在重新加載後保持不變:

user=> (defn foo [] 1) 
#'user/foo 
user=> foo 
#<user$foo [email protected]> 
user=> (def f1 foo) 
#'user/f1 
user=> (def f2 #'foo) 
#'user/f2 
user=> (defn foo [] 2) 
#'user/foo 
user=> foo 
#<user$foo [email protected]> 
user=> (f1) 
1 
user=> (f2) 
2 
+0

不錯!我看到的唯一約束是我必須在將函數作爲參數傳遞給另一個函數之前這樣做,對嗎?我試圖應用它在一個不同的功能,但得到了一個錯誤,他無法解決。除此之外,這種解決方案有什麼缺點,我可能不知道? – u6f6o

+0

您必須爲您的具體情況提供測試,以便我能理解您的意思。 – clyfe