2013-02-22 29 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