-
Notifications
You must be signed in to change notification settings - Fork 21
Fix reflection warnings #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR, I've made some comments on things to fix.
e1095ed
to
d227ba7
Compare
6c80eef
to
aca114b
Compare
src/ring/mock/request.clj
Outdated
(cond | ||
(bytes? value) | ||
(.addBinaryBody builder ^String key-name ^bytes value | ||
^ContentType mimetype ^String filename) | ||
(file? value) | ||
(.addBinaryBody builder ^String key-name ^File value | ||
^ContentType mimetype ^String filename) | ||
(instance? InputStream value) | ||
(.addBinaryBody builder ^String key-name ^InputStream value | ||
^ContentType mimetype ^String filename) | ||
:else builder))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been thinking about this change, and I think we should go about this in a different way:
(set! *warn-on-reflection* false)
(defn add-binary-body
[^MultipartEntityBuilder builder key value ^ContentType mimetype
^String filename]
(.addBinaryBody builder (name key) value mimetype filename))
(set! *warn-on-reflection* true)
The reason for this is that a reflection lookup should, in theory, be faster than checking the type with cond
, and the code is clearer and more concise.
Setting the *warn-on-reflection*
var in this way should only affect the current namespace (since it's reset on load).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't checked, but I doubt reflection will be faster than a conditional. Also hiding a problem behind manual handling of warn-on-reflection looks like a rather dodgy solution. I would argue that even String check can be added to conditional check, which will explicitly show supported types without trying to obfuscate them behind reflection . example could be:
(string? value)
(.addBinaryBody builder ^String key-name ^bytes (.getBytes ^String (:value param) ^Charset default-charset)
^ContentType mimetype ^String filename)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran some benchmarks, and you're correct. I was getting 80µs for the cond
, and 94µs with reflection.
I also think you're correct about the string check. In which case, perhaps we factor it out to a function:
(defn- str->bytes ^bytes [^String s]
(.getBytes s ^Charset default-charset))
(defn- add-binary-body
[^MultipartEntityBuilder builder key value ^ContentType mimetype
^String filename]
(let [k (name key)]
(cond
(string? value)
(.addBinaryBody builder k (str->bytes value) mimetype filename)
(bytes? value)
(.addBinaryBody builder k ^bytes value mimetype filename)
(file? value)
(.addBinaryBody builder k ^File value mimetype filename)
(instance? InputStream value)
(.addBinaryBody builder k ^InputStream value mimetype filename)
:else
(throw (IllegalArgumentException.
(str "Cannot encode a value of type " (type value)
"as a multipart body."))))))
(defn- add-multipart-part [^MultipartEntityBuilder builder k v]
(let [param (if (map? v) v {:value v})
value (if (map? v) (:value v) v)
mimetype (ContentType/parse
(or (:content-type param)
(when (file? value)
(mime/ext-mime-type (.getName ^File value)))
(if (string? value)
"text/plain; charset=UTF-8"
"application/octet-stream")))
filename (or (:filename param)
(when (file? value) (.getName ^File value)))]
(add-binary-body builder (name k) value mimetype filename)))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the way it looks now. Would be a bit more happy if instead of throwing an exception, same builder would be returned, but apart from that I am happy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's your reasoning for not throwing an exception?
549895d
to
1a6ffee
Compare
src/ring/mock/request.clj
Outdated
(or (:content-type param) | ||
(when (file? value) | ||
(mime/ext-mime-type (.getName ^File value))) | ||
(if (string? (:value param)) | ||
"text/plain; charset=UTF-8" | ||
"application/octet-stream"))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like these lines have been accidentally indented.
Looks good; merged. |
No description provided.