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 ?

>
> 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

Reply via email to