Clojure代理是否总是调用super.method()?
问题描述:
使用Clojure proxies时,传递给代理的fns
应该覆盖现有的方法还是与super.method()
一起调用?Clojure代理是否总是调用super.method()?
在以下代码中,RequestHandler.get()与代理get []
一起被调用。
;see: http://github.com/paulosuzart/JTornado
(ns org.ctornadoweb)
(import '(org.jtornadoweb Web$RequestHandler))
(import '(org.jtornadoweb HttpServer Web$Application))
(let [myHandler (proxy [Web$RequestHandler] []
(get []
(.write "Hi CLJ"))
(post []
(.write "POST")))]
(.listen
(HttpServer.
(.add (Web$Application.) "/" (class myHandler))
false nil false) 8089))
同样的情况,在编译/继承版本:
; Starts a JTornado HTTP Server and a sample RequestHandler.
; Bit verbose due to compilation directives. Recommendation is to generate
; a set of macros to hide this.
(ns org.ctornadoweb
; Compiled and implements a static main method to start the server
(:import (org.jtornadoweb HttpServer)
(org.jtornadoweb.Web$Application)
(org.jtornadoweb.Web$RequestHandler))
(:gen-class :prefix "server-"))
(gen-class
:name org.ctornadoweb.MyHandler
:extends org.jtornadoweb.Web$RequestHandler
:prefix "do")
(defn do-get [this]
"Handles the HTTP GET method"
(.write "hello clojure"))
(defn do-post [this]
"Handles the HTTP POST method"
(.write (.getArgument "name" "default" false)))
(defn server-main []
"main method"
(.listen
(org.jtornadoweb.HttpServer.
(.add (org.jtornadoweb.Web$Application.) "/" org.ctornadoweb.MyHandler)
false nil false) 8089))
;use (compile 'org.ctornadoweb)
跟踪显示代理获得被调用,然后super.get,抛出什么(默认)异常。
HTTP 405: Method Not Allowed
at org.jtornadoweb.Web$RequestHandler.get(Web.java:72)
at org.ctornadoweb.proxy$org.jtornadoweb.Web$RequestHandler$0.get(Unknown Source)
我试图找到一些关于Clojure代理的实际行为的文字。有人可以提供这种帮助吗?
答
不,超级方法不会自动调用,但您可以用proxy-super
明确地调用它。
下面的测试情况表明事情的工作,因为他们应该:
user=> (def foo
(proxy [java.util.ArrayList] []
(clear [] (println "not clearing"))))
#'user/foo
user=> (.size foo)
0
user=> (.add foo "hi")
true
user=> (.add foo "bye")
true
user=> (.size foo)
2
user=> (.clear foo)
not clearing
nil
user=> (.size foo)
2
如果super.clear()
都拿到叫,大小将显示为0。
我怀疑proxy'的'一些误用在你的身边。 'proxy'创建一个* anonymous *类。所以调用'class'是非常值得怀疑的。你应该在某处传递对象。如果你需要一个班级,你必须使用具有AOT编译功能的'gen-class'。 – kotarak 2010-07-19 07:07:19
我错在哪里?请参阅http://gist.github.com/480886生成类仍会导致相同的super.method()行为。任何想法? – paulosuzart 2010-07-20 03:17:49
您必须在前缀中指定连字符。 '(gen-class ...:prefix do- ...)'目前你的类没有看到实现,因此称为超类。 – kotarak 2010-07-20 21:42:18