(Note: This should all hopefully work, but I cannot test it at this time. Please give it your own sanity check.)
You could write
(defn download-web-page
"Downloads the webpage at the given url and returns its contents."
([^String url] (download-web-page url nil nil))
([^String url ^String user ^String password]
(with-open [client (doto (WebClient.)
(-> (.set_Credentials
(NetworkCredential. user password ""))
(->> (when user))))]
(.DownloadString client url))))
That seems pretty convoluted to me, though. Another approach:
(defn download-web-page
"Downloads the webpage at the given url and returns its contents."
([^String url] (download-web-page url nil nil))
([^String url ^String user ^String password]
(with-open [client (let [c (WebClient.)]
(when user
(.set_Credentials
(NetworkCredential. user password "")))
c)]
(.DownloadString client url))))
The convoluted ->
/ ->>
pattern from the first version could be abstracted away with a macro:
(defmacro doto-guard [guard action]
`(-> ~action ~guard))
Then you could write
(doto (WebClient.)
(doto-guard (when user) (.setCredentials ...)))
This has the nice property that you could use it multiple times in a single doto
form while mixing in regular doto
clauses. Well, it's nice if this sort of thing comes up more often in your code, anyway. Otherwise the let
-based version should do fine.
(If that pattern comes up really often for you, the macro could be made more flexible... It's also tempting to make it slightly less flexible, but prettier, say by replacing ~guard
with (when ~guard)
, so that at point of use one would write (doto-guard user (.setCredentials ...))
. Any deep reason to choose a particular version would have to come from a broader context, however.)
The split into two function bodies is just a matter of style -- I prefer not to write the nil nil
when no credentials are actually provided.