On Wed, May 18, 2011 at 7:19 PM, Lachlan <lachlan.kana...@gmail.com> wrote: > A further example of this proxy method not working would be trying to > add methods to a clojure.lang.PersistentVector. It doesn't seem to > have an <init> ??
=> (seq (.getConstructors (type []))) nil PersistentVector lacks public constructors. => (filter #(.contains (str %) "static") (.getMethods (type []))) (#<Method public static clojure.lang.PersistentVector clojure.lang.PersistentVector.create(java.lang.Object[])> #<Method public static clojure.lang.PersistentVector clojure.lang.PersistentVector.create(java.util.List)> #<Method public static clojure.lang.PersistentVector clojure.lang.PersistentVector.create(clojure.lang.ISeq)> #<Method public static java.lang.Object clojure.lang.AFn.applyToHelper(clojure.lang.IFn,clojure.lang.ISeq) throws java.lang.Exception>) It has what appear to be three static factory methods instead. Subclassing it seems unlikely to be possible. > Similarly, list is a problem. The proxy method works when you provide > a value, but PersistentList$EmptyList does not. > > It seems to work nicely with clojure.lang.PersistentArrayMap, so this > kind of thing works > > (.dosomething (proxy [clojure.lang.PersistentArrayMap user.A] [] > (dosomething [] (println (:akey this))))) > -> nil > (.dosomething (proxy [clojure.lang.PersistentArrayMap user.A] > [(into-array Object [:akey :aval])] (dosomething [] (println (:akey > this))))) > -> :aval > > ahh corners! Is there a reason not to just extend-type the type you're interested in? That is, why do you specifically want the protocol to work only with specially-created instances of String or PersistentVector or PersistentArrayMap, rather than extend it to those types and simply not use it for other instances? If you want to be able to distinguish the special instances at runtime, perhaps you'd be better off creating a wrapper object instead; or in the case of PersistentVector and PersistentArrayMap, using metadata to identify the special instances. You can even enforce it: (defprotocol Fooable (foo [this])) (extend-type clojure.lang.PersistentArrayMap Fooable (foo [this] (if (::fooable (meta this)) (println "fooed " this) (throw (Error. "not fooable"))))) (defn fooable-array-map [& args] (with-meta (apply array-map args) {::fooable true})) user=> (foo (fooable-array-map :a 1 :b 2)) "fooed {:a 1 :b 2}" nil user=> (foo (array-map :a 1 :b 2)) #<CompilerException java.lang.Error not fooable (NO_SOURCE_FILE:0)> user=> -- Protege: What is this seething mass of parentheses?! Master: Your father's Lisp REPL. This is the language of a true hacker. Not as clumsy or random as C++; a language for a more civilized age. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en