Try using resources in Clojure

Does Clojure have the Java equivalent of try-with-resources construct?

If not, what is the normal way to handle this idiom in Clojure code?

The pre-Java-7 idiom for safely opening and closing resources is detailed enough that they actually added support for using try-with-resources. It seems strange to me that I cannot find a macro for this use case in the standard Clojure library.

An example of the main project repository based on Clojure, showing how this problem is handled in practice, will be very useful.

+5
source share
2 answers

You can use with-open to bind a resource to a symbol and make sure that the resource is closed after the control thread leaves the block.

The following example is from clojuredocs.

(with-open [r (clojure.java.io/input-stream "myfile.txt")] (loop [c (.read r)] (when (not= c -1) (print (char c)) (recur (.read r))))) 

This will be expanded as follows:

 (let [r (clojure.java.io/input-stream "myfile.txt")] (try (loop [c (.read r)] (when (not= c -1) (print (char c)) (recur (.read r)))) (finally (.close r)))) 

You can see that the let block is created using try - finally for the .close() call method.

+8
source

you can do something closer to java by composing a macro on top of with-open . It might look like this:

 (defmacro with-open+ [[var-name resource & clauses] & body] (if (seq clauses) `(try (with-open [~var-name ~resource] ~@body ) ~@clauses ) `(with-open [~var-name ~resource] ~@body ))) 

so that you can submit additional offers along with the binding.

 (with-open+ [x 111] (println "body")) 

expands to a simple with-open :

 (let* [x 111] (try (do (println "body")) (finally (. x clojure.core/close)))) 

while additional sentences lead to its wrapping in try-catch:

 (with-open+ [x 111 (catch RuntimeException ex (println ex)) (finally (println "finally!"))] (println "body")) 

expands to

 (try (let* [x 111] (try (do (println "body")) (finally (. x clojure.core/close)))) (catch RuntimeException ex (println ex)) (finally (println "finally!"))) 

But still this is a rather stubborn decision.

0
source

Source: https://habr.com/ru/post/1272505/


All Articles