As a clojure beginner, I am reading clojure code to get myself familiar with Clojure's grammar. Below code snippet is a function in Ring project
(defn- request-context
"Create an UploadContext object from a request map."
{:tag UploadContext}
[request encoding]
(reify UploadContext
(getContentType [this] (get-in request [:headers "content-type"]))
(getContentLength [this] (or (req/content-length request) -1))
(contentLength [this] (or (req/content-length request) -1))
(getCharacterEncoding [this] encoding)
(getInputStream [this] (:body request))))
what is not clear to me is the line
{:tag UploadContext}
if review a clojure function's definition
(defn function-name doc-string? attr-map? [parameter-list]
conditions-map?
(expressions))
I guess (but not sure) the map should be the "attr-map?". But what is a "attr-map?"? I googled and cannot find good explanations.
any examples or links to introduce the "attr-map?" will be appreciated. I also would like to know how the attr-map is used in the code I pasted.
Passing an (optional) attr-map?
to defn
is a shorthand way of adding metadata to a function's var.
Metadata might include entries such as :tag
(runtime return type), :doc
(a documentation string) and :private
(to indicate if the var is private to a namespace). Additional pieces of metadata can also be attached there too, but should be used for data that is "orthogonal to the logical value of the data" (quote from http://clojure.org/functional_programming)
(defn greet {:tag String :other-meta-data 5} [name] (format "Hello, %s" name))
(meta #'f)
;=> {:arglists ([name]), :ns #<Namespace user>, :name f, :end-column 8, :column 1,
:line 4 :other-meta-data 5, :file "NO_SOURCE_FILE", :end-line 4,
:tag java.lang.String}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With