Search code examples
clojureclojure-java-interopedn

In EDN, how can I pass multiple values to tagged element returned from other tagged elements


I have following EDN

{
    :test #xyz/getXyz #abc/getAbc #fgh/getFgh "sampleString"
}

In Clojure, I have defined implementation for each of the tagged element which internally calls java functions. I have a requirement in which I need to pass return values of both #abc/getAbc and #fgh/getFgh to #xyz/getXyz as separate parameters. In my current implementation #fgh/getFgh gets called with "sampleString". And with the output of #fgh/getFgh, #abc/getAbc gets called. And with its output #xyz/getXyz gets called. My requirement is #xyz/getXyz should get called with return value of both #abc/getAbc and #fgh/getFgh as individual parameters.

Clojure implementation

(defn getXyz [sampleString]
    (.getXyz xyzBuilder sampleString)
)

(defn getAbc [sampleString]
    (.getAbc abcBuilder sampleString)
)

(defn getFgh [sampleString]
    (.getFgh fghBuilder sampleString)
)

(defn custom-readers []
    {
        'xyz/getXyz getXyz
        'xyz/getAbc getAbc
        'xyz/getFgh getFgh
    }
)

I want to modify getXyz to

(defn getXyz [abcReturnValue fghReturnValue]
    (.getXyz xyzBuilder abcReturnValue fghReturnValue)
)

Solution

  • You can't do exactly what you are asking. The tag can only process the following form. That said, you can alter the syntax for your Xyz EDN so that it can support taking a vector of [Abc Fgh] pair.

    {:test #xyz/getXyz [#abc/getAbc "sampleString" #fgh/getFgh "sampleString"]}
    

    I'm not sure if you meant that getAbc still needed to take getFgh as input or not. If so, it would be more like:

    {:test #xyz/getXyz [#abc/getAbc #fgh/getFgh "sampleString" #fgh/getFgh "sampleString"]}
    

    Now your getXyz tagged reader will receive a vector of Abc and Fgh. So you'll need to change your code to grab the elements from inside the vector, something like that:

    (defn getXyz [[abcReturnValue fghReturnValue]]
      (.getXyz xyzBuilder abcReturnValue fghReturnValue))
    

    This uses destructuring syntax (notice that the arguments are wrapped in an extra pair of bracket), but you could use first and second if you wanted instead, or any other way.