patternMinor
API wrapper for Clojure
Viewed 0 times
wrapperapiclojurefor
Problem
I wanted to wrap the jkeymaster library in a Clojure wrapper (for my own use, but perhaps also to save others some time). I'm just learning Clojure so I'm still not quite sure what "idiomatic libraries/APIs" look like. In Ruby, I would have created an object with methods, but in one of the clojure books they recommended letting users manage state themselves, so I have function that creates a provider, and this provider must then be passed to the register function.
Here's first an example of usage:
And here is the full text of the "library".
In addition to any general style feedback, both about the coding, and the design of the API, I'm also wondering if there is any way to have conv-listener accept either a 0 or 1-arity function. Right now I made the choice of accepting a 0-arity function,
Here's first an example of usage:
(ns keymaster.core
(:require [keymaster.keymaster :as km]))
(defn -main
"I don't do a whole lot ... yet."
[& args]
(km/register (km/provider) "control shift 1" #(println "hi")))And here is the full text of the "library".
(ns keymaster.keymaster
(:gen-class)
(:use (com.tulskiy.keymaster.common)))
(defn provider []
"Gets and initiates a keymaster provider, which must be passed to register to register shortcuts"
(let [provider (com.tulskiy.keymaster.common.Provider/getCurrentProvider true)]
(.init provider)
provider))
(defn- conv-keystroke [x]
"Takes keystroke in the form \"control shift 1\" and returns a Keystroke class"
(javax.swing.KeyStroke/getKeyStroke x))
(defn- conv-listener [f]
"Takes a function with one argument, which will get passed the keycode, and creates a listener
Todo: How to accept a function with or without a parameter to accept hotKey?"
(proxy [com.tulskiy.keymaster.common.HotKeyListener] [] (onHotKey [hotKey] (f))))
(defn register
[provider shortcut listener]
"Registers a shortcut on provider, which will trigger listener (with one argument)"
(let [k (conv-keystroke shortcut)
l (conv-listener listener)]
(.register provider k l)))In addition to any general style feedback, both about the coding, and the design of the API, I'm also wondering if there is any way to have conv-listener accept either a 0 or 1-arity function. Right now I made the choice of accepting a 0-arity function,
Solution
As a wrapper goes I think this looks fine. The feedback I do have is that I wouldn't use
For example:
does the same as
and it's easier to read and shorter. You could also do it this way:
let as often as you do and would use the treading macro (-> ...) instead. For example:
(-> (com.tulskiy.keymaster.common.Provider/getCurrentProvider true)
.init)does the same as
(let [provider (com.tulskiy.keymaster.common.Provider/getCurrentProvider true)]
(.init provider)
provider)and it's easier to read and shorter. You could also do it this way:
(.init (com.tulskiy.keymaster.common.Provider/getCurrentProvider true))Code Snippets
(-> (com.tulskiy.keymaster.common.Provider/getCurrentProvider true)
.init)(let [provider (com.tulskiy.keymaster.common.Provider/getCurrentProvider true)]
(.init provider)
provider)(.init (com.tulskiy.keymaster.common.Provider/getCurrentProvider true))Context
StackExchange Code Review Q#25575, answer score: 2
Revisions (0)
No revisions yet.