2013-02-22 28 views
0

我試圖找到一種方法來建立一個參數傳遞給這個函數(這是托盤的一部分)的函數:構建地圖傳給將解構它

(defn node-spec [& {:keys [image hardware location network qos] :as options}] 
    {:pre [(or (nil? image) (map? image))]} 
    options) 

什麼工作就是這種用法:

(node-spec :location {:location-id "eu-west-1a"}, :image {:image-id "eu-west-1/ami-937474e7"} :network {}) 

但:位置和:這個圖像位共同我想提供,而所有的機器:網絡{}位是每個節點不同。所以我想把常見的因素分解出來,做這樣的事情:

(def my-common-location-and-image {:location {:location-id "eu-west-1a"}, :image {:image-id "eu-west-1/ami-937474e7"}}) 
(node-spec (merge {:network {:security-groups [ "group1" ] }} my-common-location-and-image)) 
(node-spec (merge {:network {:security-groups [ "group1" ] }} my-common-location-and-image)) 

但這不起作用。合併的地圖被解析爲一個單一的關鍵字缺少其價值。所以,我想

(node-spec :keys (merge {:network {:security-groups [ "group1" ] }} my-common-location-and-image)) 

(node-spec :options (merge {:network {:security-groups [ "group1" ] }} my-common-location-and-image)) 

但這並不工作。我覺得我正試圖扭轉或超過節點規格參數中的解構。我究竟做錯了什麼?或者,我的目標是將一些關鍵/價值對分解爲不可能的?

回答

0

問題是node-spec函數期望一個序列而不是一個映射。這是因爲被解構的是一系列可以在鍵值對中分組的東西。

所以,強似這樣的:

{:image {:image-id "eu-west-1/ami-937474e7"}, :location {:location-id "eu-west-1a"}, :network {:security-groups ["group1"]}} 

我們需要通過這樣的:

'(:image {:image-id "eu-west-1/ami-937474e7"} :location {:location-id "eu-west-1a"} :network {:security-groups ["group1"]}) 

這意味着,這將工作:

(apply node-spec 
     (reduce concat 
       (merge {:network {:security-groups ["group1"]}} 
         my-common-location-and-image))) 
+0

是的,你的觀點大約期待我想我錯過了一個序列。但是(concat {:k「value」})產生([{:k「value」}]),那還不是嗎? – 2013-02-22 19:00:47

+0

'(concat {:k「value」})''和'(apply concat {:k「value」})'具有非常不同的效果 - 在REPL中試試看看我的意思。我可以簡單地寫成'(reduce concat {:k「value」})' - 也許這會使它更清晰(產生相同的結果)。 – Scott 2013-02-22 19:11:16

+0

好吧,爲了清晰的意圖,我已經改變了'應用concat'到'reduce concat' - 但效果是一樣的。 – Scott 2013-02-22 19:18:52