Reputation: 1290
I'm writing a small wrapper for a Java API, and I create a listener like this
(defn conv-listener [f]
(proxy [com.tulskiy.keymaster.common.HotKeyListener] [] (onHotKey [hotKey] (f))))
Is there a way in which I can make this work whether the function f
accepts 1 or zero arguments. (Ie. if f
does not accept arguments, just call it with (f)
, if it accepts an argument - which will be the value of the hotkey in this case - call it with (f hotKey)
)?
Upvotes: 2
Views: 134
Reputation: 1290
This is how we ended up solving it (pull request from Nic Marsh):
(defn arg-count [function]
"Counts the number of arguments the given function accepts"
(let [method (first (.getDeclaredMethods (class function)))
parameters (.getParameterTypes method)]
(alength parameters)))
(defn call-with-correct-args [function & args]
"Call the given function on all given args that it can accept"
(let [amount-accepted (arg-count function)
accepted-args (take amount-accepted args)]
(apply function accepted-args)))
(defn- conv-listener [function]
"Takes a function with one argument, which will get passed the keycode, and creates a listener"
(proxy [com.tulskiy.keymaster.common.HotKeyListener] []
(onHotKey [hotKey] (call-with-correct-args function hotKey))))
http://github.com/houshuang/keymaster-clj
Upvotes: 1
Reputation: 92117
No. Just call (f hotKey)
all the time, and if someone wants to use a function that ignores hotKey
then they can just pass something like (fn [_] (...do whatever...))
.
Upvotes: 4