ryoakg
4/10/2016 - 11:21 AM

with-open_and_exception.clj

;;; cf
;;;  http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.3
;;;
;;;  https://docs.oracle.com/javase/7/docs/api/java/lang/Exception.html
;;;     The class Exception and its subclasses are a form of Throwable that
;;;     indicates conditions that a reasonable application might want to
;;;     catch.
;;;
;;;  https://docs.oracle.com/javase/7/docs/api/java/lang/Error.html
;;;     An Error is a subclass of Throwable that indicates serious problems
;;;     that a reasonable application should not try to catch. Most such
;;;     errors are abnormal conditions. The ThreadDeath error, though a
;;;     "normal" condition, is also a subclass of Error because most
;;;     applications should not try to catch it.


(deftype Foo [o]
  java.io.Closeable
  (close [x]
    (.close o)
    (println "Foo closed!")))

(deftype Bar []
  java.io.Closeable
  (close [x]
    (println "Bar closed!")))

(defn danger! [x]
  (println "danger!>") (flush)
  (throw (ex-info "error!" {}))
  (println "danger!<") (flush))

;;; Usual case
(with-open [x (Foo. (Bar.))]
  (println "abc"))

;;; Exception(or Error) may cause resource leak.
(with-open [x (Foo. (danger! (Bar.)))]
  (println "abc"))

;;; Exception(or Error) safety.
(with-open [x (Bar.)
            x (danger! x)
            x (Foo. x)]
  (println "abc"))