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

标签 clojure proxy refactoring

我有一个 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的 body 进入体内proxy声明,一切正常。

我的问题:有没有办法将杂乱的细节移到单独的函数中以提高代码的可读性?

感谢您的所有想法和解决方案。

更新,2011 年 10 月 27 日:请参阅下面的评论。 Arthur Ulfeldt 尖锐地指出问题在于捕获的引用,而 Dave Ray 也正确地说你所要做的就是添加 this作为 enhanced-start-drag 的参数然后 proxy-super将正常工作。当我进行以下两项更改(对 enhanced-start-drag 的正文没有任何更改)时,我的代码又可以正常工作了:
  (defn enhanced-start-drag
    ""
    [pie this]


  (startDrag [pie]  ; IN THE PROXY STMT IN custom-selection-event-handler
   (enhanced-start-drag pie this))

顺便说一句,我的项目使用 Dave Ray 的 seesaw项目以获取 Java Swing UI。 seesaw很棒,它的文档字符串和示例代码也很棒(比大多数商业软件要好得多)。我强烈推荐它!谢谢你,戴夫!

最佳答案

你被symbol capture咬了.在这种情况下,这是有意的,但您需要保持警惕。来自 proxy-super 的文档

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

当调用进入 enhanced-start-drag 时,代理正在创建一个调用函数的类。 this 的值不是代理 super 期望的地方

您可能需要通过 this作为增强开始拖动的另一个参数,然后调用 (. saved-this ...)而不是使用代理 super 。

关于Clojure:如何从长代理语句中提取代理方法代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7909925/

相关文章:

java - "Help Arthur find his restricted class"或 "how can i make google app engine happy"

clojure - 学习如何使用 Clojure(语言)和 Closure(Google 图书馆)

java - 如何将 java.net.URL/URLConnection 与代理链一起使用

python - 无法在 Scrapy 项目中使用代理

java - 需要建议使用合适的设计模式来创建 JAVA 对象

c# - 重构我的 C# 代码 - Switch 语句

clojure - Clojure 被认为是 Lispy 还是 Schemey?

clojure - 为什么 `core.async/pipeline` 返回一个 channel ?

java - 使用 ChromeDriver 设置 browsermob 代理

c++ - 你能不用 goto 重写这段代码吗