tags:

views:

100

answers:

2

Using multimethods we are able to add methods to existing Java classes. My question is whether it is possible to redefine one specific method, and how, from Clojure code. For instance, if you have the following class,

public class Shape {
    public void draw() {
        ...
    }
}

I'd like to be able to run something to add a before method, such as this:

(attach-to-method Shape/draw :before
    (println "... about to draw a shape"))

And after evaluating that form, all subsequent calls to draw would start printing a string before performing the call itself.

My purpose with this attachment of before/after/around, AOP-like behavior, is that a framework calling that method on an existing instance can be dynamically changed and start running the newly-attached code. Currently I'm using AspectJ for that, but I'm getting to a point where using a different compiler isn't an option, and I'm curious to know if I can just ditch AspectJ.

+1  A: 

If you can't do it in Java, you can't do it in Clojure.

Brian
Isn't it more like "if you can't do it in the JVM, you can't do it in Clojure"? And thus yes, I suppose I can reformulate my question to "is it possible in the JVM", instead of in Clojure. I only filtered the language because I wanted to know if efforts had already been made to tackle this issue on Clojure, specifically.
Edgar
+4  A: 

Short answer: No.

As in Java, the only way to modify a class is to extend (subclass) it. You can extend Shape and override the draw method (assuming draw is not declared final). In Clojure, this can be accomplished with proxy or gen-class.

Stuart Sierra
Ok, thanks. I knew about `proxy` and `gen-class`, I just wanted to make sure method redefinition was still unavailable on Clojure - I had some hope that some obscure JVM recent changes whose existence I was unaware of could enable it, but I guess I'll have to stick with AspectJ, then. Thanks, Stuart and Brian!
Edgar