Search code examples
clojureclojure-java-interop

How can I parameterize access to a Java enum in clojure?


Say I have a Java enum. For example:

public enum Suits {CLUBS, DIAMONDS, HEARTS, SPADES};

Normally, I can do something in clojure with that enum like so:

(defn do-something []
   (let [s Suits/DIAMONDS] (...)))

But, I want to write a clojure function that allows the caller to specify which enum instance to use:

(defn do-something-parameterized [suit]
   (let [s  Suits/suit] (...)))

The idea is to let a caller pass in "DIAMONDS" and have the DIAMONDS enum instance get bound to s in the let.

I could have a cond match against the parameter but that seems clunkier than necessary. I suppose I could also use a macro to construct Suits/ added to suit. Is this the way to do it or is there a non-macro way that I'm missing?


Solution

  • No need for reflection or maps. Every Java enum has a static valueOf method that retrieves an enum value by name. So:

    (defn do-something-parameterized [suit]
      (let [s (Suit/valueOf (name suit))] ...))
    

    Using (name) allows either strings or keywords to be used:

    (do-something-parameterized "HEARTS")
    (do-something-parameterized :HEARTS)