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

Reply via email to