Are we generally agreed that we want to preserve the body exception,
if any, else the close exception, if any, else the body return value?

Then, without further ado:

(defmacro with-open2 [binding-exprs & body]
  (if (> (count binding-exprs) 2)
    `(with-open2 ~(vec (take 2 binding-exprs))
       (with-open2 ~(vec (drop 2 binding-exprs))
         ~@body))
    (let [[sym expr] binding-exprs]
      `(let [~sym ~expr
             res# (try
                    [(do ~@body)]
                    (catch Throwable t# t#))]
         (if (vector? res#) ; body didn't throw
           (do
             (.close ~sym) ; so let close throw
             (res# 0))
           (do ; body threw
             (try (.close ~sym) (catch Throwable _#)) ; eat close exception
             (throw res#))))))) ; and rethrow body exception

user=> (with-open [x (Foo.)] (doit x))
#<CompilerException java.lang.Exception: close exception (NO_SOURCE_FILE:242)>
user=> (with-open2 [x (Foo.)] (doit x))
#<CompilerException java.lang.Exception: doit exception (NO_SOURCE_FILE:40)>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to