On the examples for proxy, there is a binding for implementation class and interface, and another for args, which is usually left empty, ie:
(proxy [java.io.InputStream] ->[]<- (read [] -1))
Is there an example of a proxy call with inputs?
(proxy [java.io.InputStream] ->[arg0 arg1]<- (read [] -1))
These params are for the super(...) call. Let's see an example:
You could use a JFrame proxy in its simplest form (no params), and it would work:
(proxy [JFrame] [])
But JFrame has another constructor when a window title is given. So you could use that:
(proxy [JFrame] ["Window title"])
Related
I can do the following and it works...
=> (. java.awt.event.KeyEvent getKeyText 10)
"Enter"
But, I have an instance of java.awt.event.KeyEvent called ev. For example,
=> (class ev)
java.awt.event.KeyEvent
I want to call the method like this instead (but, this produces an error):
=> (. (class ev) getKeyText 10)
No matching method getKeyText found taking 1 args for class java.lang.Class
Is it possible to call a static method from an instance?
I have read the docs and searched stack overflow. The question here is not the same.
Just like in Java, you can only call static methods directly if you know at compile time what method of what class you want to call. Otherwise you need to use reflection on the Class object to find method handles.
Here is an attempt using the MethodHandle API.
(ns playground.static-method-handle
(:import [java.lang.invoke MethodType MethodHandles]))
;; Get a MethodType instance that encodes the shape of the method (return type and arguments)
(def getKeyText-method-type (MethodType/methodType String Integer/TYPE))
(defn call-getKeyText-on-class [cl key-code]
(let [lu (MethodHandles/lookup)
h (.findStatic lu cl "getKeyText" getKeyText-method-type)]
(.invokeWithArguments h [(int key-code)])))
and we use it like this:
(call-getKeyText-on-class KeyEvent 10)
;; => "Enter"
I learned that wrap-reload from ring needs to capture the var itself not the value, but what if my value is dynamically generated and not a top level var?
(defn -main [options]
(let [app (make-app options)]
;; This won't work either:
;; (run-jetty (wrap-reload #'app))
(run-jetty (wrap-reload app))
))
Clojure let bindings do not create a Var object, so you cannot use the trick of passing (var app) (or it's shortcut #'app) in place of the function object that app points to.
Please see the following for more detail: When to use a Var instead of a function?
I am using Rook framework for web services. I want to make API responses be pretty-printed. It seems that the response encoding is all handled by the wrap-restful-format function from ring.middleware.format. So I tried to replace the rook/wrap-with-standard-middleware function with my own version that passes different options through to ring.middleware.format.
(defn make-encoders-seq []
[(ring.middleware.format-response/make-encoder
(fn [s]
(json/generate-string s {:pretty true}))
"application/json")])
(defn wrap-with-standard-middleware-modified
[handler]
(-> handler
(ring.middleware.format/wrap-restful-format :formats [:json-kw :edn]
:response-options
[:encoders (make-encoders-seq)])
ring.middleware.keyword-params/wrap-keyword-params
ring.middleware.params/wrap-params))
(def handler (-> (rook/namespace-handler
["resource" 'my-app.resource])
(rook/wrap-with-injection :data-store venues)
wrap-with-standard-middleware-modified))
This compiles fine but it doesn't work to pretty print the responses, it seems like the custom encoder is never called.
Rook 1.3.9
ring-middleware-format 0.6.0
cheshire 5.4.0 (for json/generate-string in above)
Try to change your format/wrap-restful-format to:
(ring.middleware.format/wrap-restful-format :formats (concat (make-encoders-seq) [:edn])
I'm getting an IllegalArgumentException: Can't find matching method: render, leave off hints for auto match, but I need the type hints to overload the method. What am I missing...?
(defprotocol LinkRendererProtocol
(render
[this node]
[this node text]
[this node url title text]
))
(deftype LinkRenderer [handlers]
LinkRendererProtocol
(render [this ^AutoLinkNode node]
(rendering :auto-link handlers node))
(render [this ^ExpLinkNode node text]
(rendering :exp-link handlers node text))
(render [this ^ExpImageNode node text]
(rendering :exp-image-link handlers node text))
(render [this ^MailLinkNode node]
(rendering :mail-link handlers node))
(render [this ^RefLinkNode node url title text]
(rendering :ref-link handlers node url title text))
(render [this ^RefImageNode node url title alt]
(rendering :ref-image handlers node url title alt))
(render [this ^WikiLinkNode node]
(rendering :wiki-link handlers node)))
(defn link-renderer
[handlers]
(LinkRenderer. (merge default-handlers handlers)))
Protocol methods cannot be type-hinted. Even if they supported type hints, you'd probably need to put them on the protocol method declaration itself.
If you want your method to be overloaded or simply to have parameter types other than Object, you'll need to declare it as an interface method and implement that interface. You could do that from Clojure (see definterface and gen-interface) or simply include a .java file declaring that interface in your project. (It goes without saying that a method declared in this way would have to be called using interop syntax.)
Note that overloaded methods are resolved statically, so you cannot use method overloading as a replacement for chained instance? checks.
I am trying to realize a data dispatching among record constructors. The dispatching is done by a name (which is a string, received with data). And I would like each new record type to automaticaly register for dispatch. For example, in Scala, I would make something like that:
object Dispatcher {
val dispatchMap = scala.collection.mutable.Map[String, Creator]()
def += (crt: Creator) { dispatcherMap += (crt.name, crt) }
}
abstract class Creator[C <: Creation](val name: String) {
Dispatcher += this
def apply(consData: ConstructionData): C
}
So that each time an object of type Creator is created, it is registered in the Dispatcher and later can be found by it's name and passed the ConstructionData to create a Creation.
What would be an equivalent in Clojure?
I would go with map and plain old functions approach as shown below:
(ns creator)
(def dispatcher (atom {}))
(defn defcreator [name apply-fn]
(swap! dispatcher assoc name apply-fn)
apply-fn)
(defcreator :abc-creator (fn [cons-data] (do-something cons-data) ))