MEURSAULT
MEURSAULT

Reputation: 8819

Clojure metaprogramming dynamically select record (beginner!)

I have a bunch of records (A B C) that implement a protocol P.

I want to write a method which will select one of the types of records, construct it, and then call a method on it.

For example, if I have a list of the records (def types '(A B C)) I want to do something like (->(first types) 1 2 3)

Upvotes: 3

Views: 82

Answers (1)

Magos
Magos

Reputation: 3014

Well, functions are also values and can be stored in and retrieved from data structures. So you should be able to just store the constructor functions you want to pick from in some convenient format and use them from there. Something like:

(defrecord foo [x y])

(defrecord bar [x y z])

(def constructors [->foo ->bar])

((first constructors) 4 5) ;;=> #user.foo{:x 4, :y 5}

;;or

(apply (second constructors) [20 true :baz]) ;;=> #user.bar{:x 20, :y true, :z :baz}

(-> (second constructors) (apply '(59 -30 false))) ;;=> #user.bar{:x 59, :y -30, :z false}

or you can even skip the data structure entirely:

(defn quxx [n a-map]
  ((if (< 25 n) map->foo map->bar) a-map))

(quxx 2 {:x 3 :y 9 :z -200}) ;;=> #user.bar{:x 3, :y 9, :z -200}

(quxx 29 {:x 3 :y 9 :z -200}) ;;=> #user.foo{:x 3, :y 9, :z -200}

Upvotes: 1

Related Questions