Stian Håklev
Stian Håklev

Reputation: 1290

How to make java API wrapper work with different function arities?

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

Answers (2)

Stian Håklev
Stian Håklev

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

amalloy
amalloy

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

Related Questions