UPDATE:
Thanks for all the help so far. This is my new code, which works. But not exactly as I would like it to.
I need it to return the java exception (don't ask me why).
Example:
(safe (/ 1 0))
#<ArithmeticException java.lang.ArithmeticException: Divide by zero>
which is how I want it to be. But when I make use of the other clauses of code that handle bindings etc, I get the Clojure exception:
(seefe [f(FileReader.(File. "C:/txtf.txt"))](. f read))
FileNotFoundException C:\txtf.txt (The system cannot find the file specified) java.io.FileInputStream.open (:-2)
What can I do to prevent this, and show the Java exception instead?
(defmacro safe [bindings & code]
(if (list? bindings)
`(try
(println "line 8: try")
~bindings
(catch Throwable e# e#))
(if (= (count bindings) 0)
`(try ~code
(catch Throwable e# e#))
`(let ~(subvec bindings 0 2)
(try
(safe ~(subvec bindings 2) ~@code)
(catch Throwable e# e#)
(finally
(. ~(bindings 0) close)))))))
OLD
I'm trying to get an assignment done, but it's impossible without any tutoring. My teachers expect us to teach ourselves Clojure in 1 week and complete this assignment. Everyone in my class is stuck and we already hate the teacher, lmao.
Okay, so the macro is supposed to be able to try code, and return a result or an exception. It's supposed to be able to handle expressions like:
(def v (safe [s (FileReader. (File. "file.txt"))] (. s read)))
If the code opened any filestreams or whatnot, it should close them in a finally clause. This is what I got so far - I realize it's not working.
(defmacro safe [& body]
`(try ~@body
(catch Throwable e# e#)
(finally
(if (. ~@body isInstance Closable) (. ~@body close)))))
The error I get is:
Unable to resolve symbol: s in this context, compiling:(NO_SOURCE_PATH:1)
I got desperate so I tried alot of different stuff, I tried:
to edit the macro:
(defmacro safe [& body]
`(try ~@body
(catch Throwable e# e#)
(finally (if (. ~@body isInstance Closable) (. ~@body close)))))
then run:
(safe (. (java.io.FileReader. (java.io.File. "C:/Users/Dyallo.L/Dropbox/DVK11/PROP/Clojure/txt.txt")) read))
Which resulted in:
No such var: clooj.cemerick.pomegranate/Closable, compiling:(NO_SOURCE_PATH:1)
Someone mentioned the macro WITH-OPEN but I guess that won't work well with my generic macro. The macro isn't meant for opening files, but if they are, it should definately close them.
So darn, won't you give me a hand Stackoverflow-geniuses? Thanks in beforehand.