Clojure:try,catch宏,它也关闭任何文件流(不打开) [英] Clojure: try, catch macro that also closes any filestreams (not with-open)

查看:276
本文介绍了Clojure:try,catch宏,它也关闭任何文件流(不打开)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

UPDATE:



感谢所有的帮助。这是我的新代码,它的工作。但不完全是我想要的。

我需要它来返回java异常(不要问我为什么)。
例如:



(safe(/ 10))

#< ArithmeticException java.lang。 ArithmeticException:除以零>


这是我想要的方式。但是当我使用处理绑定等代码的其他条款,我得到Clojure异常:

 (seefe [f (FileReader。(File。C:/txtf.txt))](。f read))
FileNotFoundException C:\txtf.txt(系统找不到指定的文件)java.io.FileInputStream。 open(:-2)

我可以如何防止这种情况,并显示Java异常?






 (defmacro safe [bindings& code] 
(list?bindings)
`(try
(printlnline 8:try)
〜bindings
(catch Throwable e#e#))

(try〜($ bind $ 0)
(try〜code
(catch Throwable e#e#))
`(let〜(subvec bindings 0 2)

(safe〜(subvec bindings 2)〜@ code)
(catch Throwable e#e#)
(finally
〜(bindings 0)close))))))))






OLD



我想要完成作业,但没有任何辅导,这是不可能的。我的老师希望我们在1周内教我们Clojure并完成这项任务。我的班级里的每个人都被困住了,我们已经讨厌老师了,lmao。



好吧,所以宏应该能够尝试代码,并返回结果或例外。它应该能够处理如下的表达式:

 (def v(safe [s(FileReader。 txt))](。s read)))

如果代码打开任何filestreams或whatnot,它应该在finally子句中关闭它们。
这是我到目前为止 - 我意识到它不工作。

 (defmacro safe [& body] 
`(try〜@ body
(catch Throwable e#e#)
(finally
(if(。〜@ body isInstance Closable)(。〜@ body close))) )

我得到的错误是:



< >

无法解析此上下文中的符号:
编译:(NO_SOURCE_PATH:1)


我绝望,所以我尝试了很多不同的东西,我尝试:

 编辑宏:

(defmacro safe [& body]
`(try〜@ body
(catch Throwable e#e#)
(finally(if(。〜@ body isInstance Closable) @body close)))))

然后运行:

 (safe(。(java.io.FileReader。(java.io.File。C:/Users/Dyallo.L/Dropbox/DVK11/PROP/Clojure/ txt.txt))read))

其结果是:


没有这样的变量:clooj.cemerick.pomegranate / Closable,
编译:(NO_SOURCE_PATH:1)


有人提到宏WITH-OPEN,但我想这将不能很好地与我的通用宏。这个宏不是用来打开文件的,但如果它们是,它应该明确地关闭它们。



这样darn,你不会给我一个手Stackoverflow-天才?
先谢谢。

解决方案

with-open 完全一样。 / p>

如果有变量(可以多于一个)绑定到创建的对象,它将 body $ c> try-catch 阻止与最终关闭。

 code>(使用-f开启[f(FileReader。(File。1.txt))] 
(用f做这个)
))

=>
(clojure.core / let
[f(FileReader。(File。1.txt))]
(try(clojure.core / with-open []
(使用f)
(使用f))
(finally(。f clojure.core / close))))

如果没有绑定,那么它只是返回正文

 宏展开式-1'(with-open [] 
(用f做这个操作)
(用f做的)))

=>
(do(with f)
(do that with f))

更新。Arthur已解释了您的问题的例外部分。


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.

解决方案

with-open macro does exactly the same thing.

If there is variable (can be more than one) bound to created object it wraps the body to try-catch block with finallyclosing.

(macroexpand-1 '(with-open [f (FileReader. (File. "1.txt"))]
                  (do this with f)
                  (do that with f)))

=>
(clojure.core/let
 [f (FileReader. (File. "1.txt"))]
 (try (clojure.core/with-open []
        (do this with f)
        (do that with f))
      (finally (. f clojure.core/close))))

If there are no bindings then it just returns the body

(macroexpand-1 '(with-open []
                  (do this with f)
                  (do that with f)))

=>
(do (do this with f)
    (do that with f))

Update. Arthur has already explained "exception" part of your question.

这篇关于Clojure:try,catch宏,它也关闭任何文件流(不打开)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆