On Wed, Jul 8, 2009 at 10:23 AM, Nicolas Buduroi<nbudu...@gmail.com> wrote:
>
>> If you know the method you wish to call, do you not know the class and can
>> thus call the static method directly?
>
> Well that was the point of the question, that is if I have to call a
> static method on a class we don't know in advance. I understand this
> capability isn't that useful and is quite rarely used, but maybe
> somebody will one day need it for some practical reason. ;-)

Lets say you want to call static method "foo" of a class,
but you don't know which class -- you want this to be
specified at runtime in a parameter.  Something like this:

(defn map-foo [cls coll]
  (map cls/foo coll))      ; doesn't work

As mentioned by others, one approach is to use reflection,
either Java's API or Clojure's (undocumented,
may-change-without-warning) wrapper:

(defn map-foo [cls coll]
  (map #(clojure.lang.Reflector/invokeStaticMethod
           cls "foo" (to-array [%]))
       coll))

(map-foo MyClass [1 2 3 4])

This works, but if you're allowed to adjust the requirements
a bit, a better solution is possible.  What if your user
called:

(map-foo #(MyClass/foo %) [1 2 3 4])

This can be done without any runtime reflection at all,
which can greatly boost the runtime speed.  Also, it's more
flexible:  I *told* you to name your method "foo" but
I guess I should have been more explicit.  Oh well, no
matter:

(map-foo #(YourClass/Foo %) [1 2 3 4])

Or if your user is using Clojure rather than Java, they
don't even have to use a class:

(map-foo #(her-do-foo-thing %) [1 2 3 4])

or just:

(map-foo her-do-foo-thing [1 2 3 4])

Best of all implementing map-foo is simpler:

(defn map-foo [f coll]
  (map f coll))

Which in this trivial example means you can just use 'map'
instead of 'map-foo'.  But even in a less trivial example
you may find this approach more workable all around.

Now if you were going to do more than one thing on the class
(call static methods foo, bar, and baz, for example) things
get more complicated.  You may be able to pass around a map
of fns, perhaps assisted by a macro.  ...or you may decide
that reflection is better after all.

(map-things {:foo #(MyClass/foo %)
             :bar #(MyClass/bar %)
                         :baz #(MyClass/baz %)}
                        coll)

(map-things (static-method-map MyClass [foo bar baz]) coll)

--Chouser

--~--~---------~--~----~------------~-------~--~----~
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