Clojure:如何从长代理语句中提取代理方法代码?

发布于 2024-12-12 06:19:18 字数 2375 浏览 0 评论 0原文

我有一个 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-dragbody 没有任何更改)时,我的代码再次工作:

  (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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

败给现实 2024-12-19 06:19:18

您已被符号捕获< /a>。在这种情况下,这是故意的,但您需要保持警惕。从 proxy-super 的文档来看,

Use to call a superclass method in the body of a proxy method. 
Note, expansion captures 'this`

代理正在创建一个调用函数的类,当调用进入 enhanced-start-dragthis 的值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

Use to call a superclass method in the body of a proxy method. 
Note, expansion captures 'this`

proxy is creating a class that calls a function, when the call gets into enhanced-start-drag the value of this is not where proxy-super expects

you may needs to pass this as another argument into enhanced-start-drag and then call (. saved-this ...) instead of using proxy-super.


~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文