Greetings. I'm not understanding proxies. Can anyone advise me what I'm missing?
I try the following: user=> (def m (proxy [java.util.HashMap] [] (finalize [] ;(proxy-super finalize) (prn "finalizing...")) (hashCode [] 99))) #'user/m user=> (.hashCode m) 99 user=> (.finalize m) IllegalArgumentException No matching field found: finalize for class user.proxy$java.util.HashMap$0 clojure.lang.Reflector.getInstanceField (Reflector.java:289) user=> (ancestors m) nil user=> (the 'proxy-super' is commented out, just to reassure myself that its presence is not somehow the root of the problem) I'm afraid that the documentation of the 'proxy' macro is too terse for me to work out what's supposed to be happening here. The documentation says that 'proxy' "creates a instance of a proxy class that implements the named class/interface(s) by calling the supplied fns." That suggests (without quite saying so) that 'm' should be an extension of class java.util.HashMap, in this case, and this is corroborated by the remark that "If a method fn is not provided for a class method, the _superclass_ methd will be called" (my emphasis, note the docs' misspelling of 'methd'). However, the null result of (ancestors m) suggests instead that 'm' extends only Object, and that it handles _all_ of its method calling by delegation through reflection on the class being proxied. It's the second interpretation that seems to explain why I can't override protected method 'finalize' (although that would suggest that I could create a new method 'finalize', which shadows Object.finalize without overriding it, and doesn't really explain why I'm seeing this error). That said, however, the docs stress that "Note that while method fns can be provided to override protected methods...", which seems to say that what I'm trying to do, here, should be possible. The rest of that sentence seems to suggest that something more complicated is happening, without revealing quite what. Also Fogus and Houser (in The Joy of Clojure, p211) give an example of using 'proxy', in which they illustrate a function proxying FilterOutputStream, and say that "The proxy returned by screaming-filter extends the Java class java.io.FilterOutputStream". That seems to suggest that the proxy is indeed a subclass of the thing it's proxying. Finally, the on-line discussion of gen-class at <http://clojure.org/compilation> mentions that one of the facilities it provides is "Exposing inherited protected members". However the description of gen-class, there, does strongly suggest that it's a heavyweight, exotic thing, intended for fuller JVM interop rather than everyday use, and is telling me, in effect, "these aren't the macros you're looking for; move along". It sounds as if getting involved in gen-class in this context would be an unidiomatic way of doing something fairly simple, namely producing an anonymous extension of a class which overrides a protected method. What am I missing? Thanks for any pointers. Best wishes, Norman -- Norman Gray : http://nxg.me.uk -- 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