On Fri, Jan 1, 2010 at 2:58 PM, Stuart Sierra <the.stuart.sie...@gmail.com> wrote: > I should have brought this up before 1.1 was released, but I'm > bothered by the change of clojure.core/import from a function to a > macro. > > If I'm creating a namespace dynamically, I can't evaluate the name of > the class I want to pass to import. The only way is to use > undocumented Java functions, like: > > (defn import-name > "Import a class named c (a String) into namespace n." > [n c] > (.importClass n (clojure.lang.RT/classForName c))) > > Of course, I can write a macro that evaluates the strings, but that's > not really what I want. I want the equivalent of clojure.core/intern > for classes. Is there a better way? >
Your example highlights the problem addressed by making import a macro. Basically, Class.forName can't be proxied, i.e. any indirection (such as wrapping it in a helper function like you did) breaks the magic hack inside Class.forName that finds the classloader of the caller by walking a fixed distance on the stack. Thus, such proxied imports don't play well with specialized modular classloading architectures (like OSGi etc) that expect you to be calling Class.forName for any dynamic use. In such cases, you will be seeing what the classloader of the wrapping function can see, rather than what the caller can see. On the path towards fixing this, I've added a (currently undocumented) special op - clojure.core/import*, which will emit bytecode for a call to Class.forName at the point of call (plus all the other stuff needed to bind in the current namespace). This will ensure correct resolution in the classloader of the caller. import expands into calls to import*. Note it is String-based. This too is critical. user=> (clojure.core/import* "java.util.List") java.util.List user=> List java.util.List Note that, as a special op, import* still is not a function. The bottom line is no ordinary function or method can do this job. If you want to use import* as a workaround, please consider it alpha and subject to change. Rich -- 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