2014-03-06 67 views
3

我需要一個功能,可以細化amazonicasqs/receive-message以添加默認的等待時間。該函數需要一個隊列URL,然後接受任意數量的可選命名參數,這些參數應該一直傳遞到sqs/receive-message。我想這樣稱呼它:在Clojure中委託代理命名參數的習慣方式

(my-receive-message "https://sqs.us-east-1.amazonaws.com/123/test-q" 
        :max-number-of-messages 10 
        :delete true) 

這將導致調用sqs/receive-message這樣的:

(sqs/receive-message :queue-url "https://sqs.us-east-1.amazonaws.com/123/test-q" 
        :wait-time-seconds 20 
        :max-number-of-messages 10 
        :delete true) 

這是我多麼希望自己相當經常做的,但我避風港」 t找到了一個不錯的方法呢。有沒有一種慣用的方式來做到這一點?

回答

5

在合併的參數上使用apply

(defn my-receive-message 
    [url & {:as args}] 
    (apply sqs/receive-message (-> {:queue-url url 
            :wait-time-seconds 20} 
           (merge args) 
           seq 
           flatten))) 
+0

破壞args params怎麼樣?此外,您可能想要合併其他方式,因此my-receive-message的調用者可以覆蓋默認的等待 – DanLebrero

+0

謝謝 – DanLebrero

+0

取得的點數![url] {:as args}](避免應用哈希映射參數) –

1

你總是可以編寫一個宏:

(defmacro my-receive-message [url & opts] 
    `(sqs/receive-message 
     [email protected](flatten (seq (merge {:queue-url url :wait-time-seconds 20} 
          (apply hash-map opts)))))) 

(請注意,這樣做幾乎完全一樣的東西作爲吉列爾莫的功能的主要區別是,你不必apply sqs/receive-message - 非引用剪接([email protected])隱式地處理apply部分。)

+2

這真的很不錯,但是從我讀過的每本Clojure書中的「喜歡函數到宏」這些詞仍然在我耳中響起。 ;) –

+0

這通常是一個很好的經驗法則。現在Guillermo的功能更簡單/更時尚,這要歸功於解構,我想我也可能會使用功能版本。好電話,dAni! –