On Thu Mar 17 21:49 2011, Fiel Cabral wrote:
> Hello Clojure users,
> This is a dumb question but I'd like to write something equivalent to this
> in Clojure:
>
> public String loop_with_exception(int retries)
> {
> for (int n = retries; n > 0; n--) {
> try {
> return some_io_operation();
> } catch (IOException e) {
> continue;
> }
> }
> return null;
> }
>
> So I tried writing it like this:
>
>
> (ns sandbox.core
> (:import [java.io.IOException]))
>
> (defn some-io-operation
> "Some read I/O operation that could throw an IOException."
> []
> (println "WOULD do a read operation"))
>
> (defn loop-with-exception [retries]
> (loop [n retries]
> (try
> (when (pos? n)
> (some-io-operation))
> (catch IOException e
> (recur (dec n))))))
>
> What's the recommended way to handle exceptions and retry inside a
> loop/recur?
Well, I'm not sure what's the best recommendation, but playing around
with it a bit, it seems like moving the exception-handling into the IO
method works best. Doing this, you can have different return values
depending on whether the operation succeeded.
Here's what I came up with:
(defn some-io-operation
"Some read I/O operation that may fail. Returns nil on failure,
::success on success."
[]
(try
(when (zero? (rand-int 3))
(throw (IOException.)))
; return non-nil and non-false on success
::success
(catch IOException e
; return nil on failure
nil)))
(defn loop-with-exception [retries]
(first (remove nil? (repeatedly retries some-io-operation))))
I am not absolutely certain the loop-with-exception function is the best
implementation, but I believe it works correctly.
Sincerely,
Daniel Solano Gómez
pgpzctxncuNQV.pgp
Description: PGP signature
