2014-03-06 26 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! –