On Jan 25, 2:30 pm, Laurent PETIT <laurent.pe...@gmail.com> wrote: > 2011/1/25 Shantanu Kumar <kumar.shant...@gmail.com>: > > > The changed code should catch 'Exception', not 'Throwable' because the > > latter is a common ancestor of both 'Exception' and 'Error'. An > > 'Error' must not be swallowed at any point in the system, unless you > > are writing an app server or a JVM implementation. ;-) > > True enough. > > Does this mean that, with the change from Throwable to Exception, > you're ok with the new implementation and it fullfills the > expectations of your original email ?
Yes. Regards, Shantanu > > > > > > > > > > > Regards, > > Shantanu > > > On Jan 25, 6:11 am, Ken Wesson <kwess...@gmail.com> wrote: > >> On Mon, Jan 24, 2011 at 7:43 PM, Laurent PETIT <laurent.pe...@gmail.com> > >> wrote: > >> > 2011/1/25 Ken Wesson <kwess...@gmail.com>: > >> >> Ah, I guess it may be a bit cleaner to just eschew "finally" > >> >> altogether and close in the try and in the catch. The one thing that's > >> >> a bit icky about that is that if the body close throws, the catch > >> >> clause tries to close the stream again. > > >> > argh yes, this may be a problem ... > > >> There's also a bug: _ instead of _# in the close exception discarder. :) > > >> How's about: > > >> (in-ns 'clojure.core) > >> (defmacro with-open > >> "bindings => [name init ...] > > >> Evaluates body in a try expression with names bound to the values > >> of the inits, and a finally clause that calls (.close name) on each > >> name in reverse order." > >> {:added "1.0"} > >> [bindings & body] > >> (assert-args with-open > >> (vector? bindings) "a vector for its binding" > >> (even? (count bindings)) "an even number of forms in binding vector") > >> (cond > >> (= (count bindings) 0) `(do ~@body) > >> (symbol? (bindings 0)) `(let ~(subvec bindings 0 2) > >> (let [res# (try > >> (with-open ~(subvec > >> bindings 2) ~@body) > >> (catch Throwable t# > >> (try > >> (. ~(bindings 0) close) > >> (catch Throwable _#)) > >> (throw t#)))] > >> (. ~(bindings 0) close) > >> res#)) > >> :else (throw (IllegalArgumentException. > >> "with-open only allows Symbols in bindings")))) > > >> No double-closing and no vector. If the body throws, the exception is > >> caught, the close is done with any close exception suppressed, and the > >> original exception rethrown and that's it. If the body doesn't throw, > >> we store it in res and then close. If the close throws here, the > >> exception is allowed to propagate. Otherwise we return res. > > >> I've tested this with Foo and it works; modifying Foo to replace the > >> close throw with (println "closed"), the doit throw with the integer > >> literal 42, or both, I get: > > >> Both throw: > >> #<CompilerException java.lang.Exception: doit exception > >> (NO_SOURCE_FILE:46)> > > >> Close throws: > >> #<CompilerException java.lang.Exception: close exception > >> (NO_SOURCE_FILE:48)> > > >> Doit throws: > >> closed > >> #<CompilerException java.lang.Exception: doit exception > >> (NO_SOURCE_FILE:46)> > > >> Neither throws: > >> closed > >> 42 > > >> The right exception escapes if any exceptions are thrown, and "closed" > >> is printed exactly once if close doesn't throw. > > > -- > > 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 -- 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