Clojure:如何从长代理语句中提取代理方法代码?
我有一个 Clojure proxy
语句,该语句变得庞大且混乱,因此我决定尝试将 beginDrag
方法重新定义的代码从 proxy
语句,如下所示:
(defn enhanced-start-drag
""
[pie]
(let [pobj (. pie getPickedNode)
pobj-coll (seq (.. pie getInputManager
getKeyboardFocus getSelection))]
(println pobj)
(println pobj-coll)
(println "----------")
(proxy-super startDrag pie))) ; THIS IS LINE 94 (SEE ERROR MSG)
(defn custom-selection-event-handler [marqueeParent selectableParent]
(proxy [PSelectionEventHandler] [marqueeParent selectableParent]
(decorateSelectedNode [node]
(let [stroke-color (Color/red)]
(.setStrokePaint node stroke-color)))
(undecorateSelectedNode [node]
(let [stroke-color (Color/black)]
(.setStrokePaint node stroke-color)))
(startDrag [pie] ; pie is a PInputEvent
(enhanced-start-drag pie))
(endStandardSelection [pie] ; pie is a PInputEvent
(let [pobj (.getPickedNode pie)
slip (. pobj getAttribute "slip")
]
(swap! *last-slip-clicked*
(fn [x] slip))))))
我收到以下编译错误:
cd /Users/gw/tech/clojurestuff/cljprojects/infwb/src/infwb/
1 compiler notes:
Unknown location:
error: java.lang.Exception: Unable to resolve symbol: this in this context
core.clj:94:5:
error: java.lang.Exception: Unable to resolve symbol: this in this context
(core.clj:94)
Compilation failed.
一旦将 enhanced-start-drag
的正文恢复到 proxy
语句的正文中,一切正常。
我的问题:有没有办法将混乱的细节移到单独的函数中以提高代码的可读性?
感谢您的所有想法和解决方案。
更新,2011 年 10 月 27 日:请参阅下面的评论。 Arthur Ulfeldt 尖锐地指出问题是捕获的引用,Dave Ray 也正确地指出,您所要做的就是将 this
作为参数添加到 enhanced-start-drag
然后 proxy-super
将正常工作。当我进行以下两项更改(对 enhanced-start-drag
的 body 没有任何更改)时,我的代码再次工作:
(defn enhanced-start-drag
""
[pie this]
顺便说
(startDrag [pie] ; IN THE PROXY STMT IN custom-selection-event-handler
(enhanced-start-drag pie this))
一句,我的项目使用 Dave Ray 的用于获取 Java Swing UI 的 seesaw
项目。 seesaw 很棒,它的文档字符串和示例代码也很棒(比大多数商业软件要好得多)。我强烈推荐它!谢谢你,戴夫!
I have a Clojure proxy
statement that was getting large and messy, so I decided to try factoring the code of the beginDrag
method redefinition out of the proxy
statement, like this:
(defn enhanced-start-drag
""
[pie]
(let [pobj (. pie getPickedNode)
pobj-coll (seq (.. pie getInputManager
getKeyboardFocus getSelection))]
(println pobj)
(println pobj-coll)
(println "----------")
(proxy-super startDrag pie))) ; THIS IS LINE 94 (SEE ERROR MSG)
(defn custom-selection-event-handler [marqueeParent selectableParent]
(proxy [PSelectionEventHandler] [marqueeParent selectableParent]
(decorateSelectedNode [node]
(let [stroke-color (Color/red)]
(.setStrokePaint node stroke-color)))
(undecorateSelectedNode [node]
(let [stroke-color (Color/black)]
(.setStrokePaint node stroke-color)))
(startDrag [pie] ; pie is a PInputEvent
(enhanced-start-drag pie))
(endStandardSelection [pie] ; pie is a PInputEvent
(let [pobj (.getPickedNode pie)
slip (. pobj getAttribute "slip")
]
(swap! *last-slip-clicked*
(fn [x] slip))))))
I get the following compile error:
cd /Users/gw/tech/clojurestuff/cljprojects/infwb/src/infwb/
1 compiler notes:
Unknown location:
error: java.lang.Exception: Unable to resolve symbol: this in this context
core.clj:94:5:
error: java.lang.Exception: Unable to resolve symbol: this in this context
(core.clj:94)
Compilation failed.
As soon as I restore the body of enhanced-start-drag
into the body of the proxy
statement, everything works.
My question: Is there a way to move the messy details out to a separate function to improve the readability of my code?
Thanks for all your ideas and solutions.
UPDATE, 10/27/11: See the comments below. Arthur Ulfeldt was sharp in pointing out that the issue is captured references, and Dave Ray is also correct in saying that all you have to do is add this
as a parameter to enhanced-start-drag
and then proxy-super
will work correctly. When I made the following two changes (without any changes to the body of enhanced-start-drag
), my code was working again:
(defn enhanced-start-drag
""
[pie this]
and
(startDrag [pie] ; IN THE PROXY STMT IN custom-selection-event-handler
(enhanced-start-drag pie this))
BTW, my project uses Dave Ray's seesaw
project to get a Java Swing UI. seesaw
is awesome, as are its docstrings and sample code (which are much better than most commercial software). I highly recommend it! And thank you, Dave!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您已被符号捕获< /a>。在这种情况下,这是故意的,但您需要保持警惕。从
proxy-super
的文档来看,代理正在创建一个调用函数的类,当调用进入
enhanced-start-drag
时this
的值code> 不是 proxy-super 期望的地方,您可能需要将
this
作为另一个参数传递到enhanced-start-drag,然后调用(.saved-this ...)
而不是使用代理超级。You have been bitten by symbol capture. In this case it is intentaional though you need to stay aware of it. From the doc for
proxy-super
proxy is creating a class that calls a function, when the call gets into
enhanced-start-drag
the value ofthis
is not where proxy-super expectsyou may needs to pass
this
as another argument into enhanced-start-drag and then call(. saved-this ...)
instead of using proxy-super.