Public Vars

Back

reify (clj)

(source)

macro

(reify & opts+specs)
reify creates an object implementing a protocol or interface. reify is a macro with the following structure: (reify options* specs*) Currently there are no options. Each spec consists of the protocol or interface name followed by zero or more method bodies: protocol-or-interface-or-Object (methodName [args+] body)* Methods should be supplied for all methods of the desired protocol(s) and interface(s). You can also define overrides for methods of Object. Note that the first parameter must be supplied to correspond to the target object ('this' in Java parlance). Thus methods for interfaces will take one more argument than do the interface declarations. Note also that recur calls to the method head should *not* pass the target object, it will be supplied automatically and can not be substituted. The return type can be indicated by a type hint on the method name, and arg types can be indicated by a type hint on arg names. If you leave out all hints, reify will try to match on same name/arity method in the protocol(s)/interface(s) - this is preferred. If you supply any hints at all, no inference is done, so all hints (or default of Object) must be correct, for both arguments and return type. If a method is overloaded in a protocol/interface, multiple independent method definitions must be supplied. If overloaded with same arity in an interface you must specify complete hints to disambiguate - a missing hint implies Object. recur works to method heads The method bodies of reify are lexical closures, and can refer to the surrounding local scope: (str (let [f "foo"] (reify Object (toString [this] f)))) == "foo" (seq (let [f "foo"] (reify clojure.lang.Seqable (seq [this] (seq f))))) == (\f \o \o)) reify always implements clojure.lang.IObj and transfers meta data of the form to the created object. (meta ^{:k :v} (reify Object (toString [this] "foo"))) == {:k :v}

Examples

logseq/logseq
(ns frontend.pubsub
  "All mults and pubs are collected to this ns.
  vars with suffix '-mult' is a/Mult, use a/tap and a/untap on them. used by event subscribers
  vars with suffix '-pub' is a/Pub, use a/sub and a/unsub on them. used by event subscribers
  vars with suffix '-ch' is chan used by event publishers."
  {:clj-kondo/config {:linters {:unresolved-symbol {:level :off}}}}
  #?(:cljs (:require-macros [frontend.pubsub :refer [def-mult-or-pub chan-of]]))
  (:require [clojure.core.async :as a :refer [chan mult pub]]
            [clojure.core.async.impl.protocols :as ap]
            [malli.core :as m]
            [malli.dev.pretty :as mdp]
            [clojure.pprint :as pp]))

;;; helper macro
(defmacro chan-of [malli-schema malli-schema-validator & chan-args]
  `(let [ch# (chan ~@chan-args)]
     (reify
       ap/ReadPort
       (~'take! [~'_ fn1-handler#]
        (ap/take! ch# fn1-handler#))
       ap/WritePort
       (~'put! [~'_ val# fn1-handler#]
        (if (~malli-schema-validator val#)
          (ap/put! ch# val# fn1-handler#)
          (do (mdp/explain ~malli-schema val#)
              (throw (ex-info "validate chan value failed" {:val val#}))))))))
pedestal/pedestal
(ns io.pedestal.http.jetty.container
  (:require [io.pedestal.http.container :as container]
            [clojure.core.async :as async])
  (:import (java.nio.channels ReadableByteChannel)
           (java.nio ByteBuffer)
           (org.eclipse.jetty.server Response)))

(extend-protocol container/WriteNIOByteBody
  org.eclipse.jetty.server.Response
  (write-byte-channel-body [servlet-response ^ReadableByteChannel body resume-chan context]
    (let [os ^org.eclipse.jetty.server.HttpOutput (.getHttpOutput servlet-response)]
      (.sendContent os body (reify org.eclipse.jetty.util.Callback
                                   (succeeded [this]
                                     (.close body)
                                     (async/put! resume-chan context)
                                     (async/close! resume-chan))
                                   (failed [this throwable]
                                     (.close body)
                                     (async/put! resume-chan (assoc context :io.pedestal.impl.interceptor/error throwable))
                                     (async/close! resume-chan))))))
  (write-byte-buffer-body [servlet-response ^ByteBuffer body resume-chan context]
    (let [os ^org.eclipse.jetty.server.HttpOutput (.getHttpOutput servlet-response)]
      (.sendContent os body (reify org.eclipse.jetty.util.Callback
                                   (succeeded [this]
                                     (async/put! resume-chan context)
                                     (async/close! resume-chan))
                                   (failed [this throwable]
                                     (async/put! resume-chan (assoc context :io.pedestal.impl.interceptor/error throwable))
                                     (async/close! resume-chan)))))))
typedclojure/typedclojure
(ns ^:no-doc typed.clj.ext.clojure.core__reify
  "Typing rules clojure.core/reify"
  (:require [clojure.core.typed.internal :as internal]
            [typed.cljc.checker.check :as chk]
            [typed.cljc.analyzer :as ana2]
            [typed.cljc.checker.check.unanalyzed :refer [defuspecial]]))

;;======================
;; clojure.core/reify

(defuspecial defuspecial__reify
  "defuspecial implementation for clojure.core/reify"
  [{original-reify-form :form :as original-expr} expected]
  (-> original-expr
      ana2/analyze-outer
      ((fn [expr]
         {:pre [(= :unanalyzed (:op expr))]
          :post [(= :unanalyzed (:op %))]}
         (update expr :form (fn [form]
                              {:pre [(= 'reify* (first form))]}
                              (-> (list* (vary-meta (first form) assoc ::original-reify-expr original-expr)
                                         (rest form))
                                  (with-meta (meta form)))))))
      (chk/check-expr expected)))
clojure/core.rrb-vector
(ns clojure.core.rrb-vector.transients
  (:require [clojure.core.rrb-vector.parameters :as p]
            [clojure.core.rrb-vector.nodes :refer [ranges last-range
                                                   overflow?]])
  (:import (clojure.core.rrb_vector.nodes NodeManager)
           (clojure.core ArrayManager)
           (java.util.concurrent.atomic AtomicReference)))

(def ^ITransientHelper transient-helper
  (reify ITransientHelper
    (editableRoot [this nm am root]
      (let [new-arr (clojure.core/aclone ^objects (.array nm root))]
        (if (== 33 (alength ^objects new-arr))
          (aset new-arr 32 (aclone (ints (aget ^objects new-arr 32)))))
        (.node nm (AtomicReference. (Thread/currentThread)) new-arr)))
clojure/core.rrb-vector
(ns clojure.core.rrb-vector.transients
  (:require [clojure.core.rrb-vector.parameters :as p]
            [clojure.core.rrb-vector.nodes :refer [ranges last-range
                                                   overflow?]])
  (:import (clojure.core.rrb_vector.nodes NodeManager)
           (clojure.core ArrayManager)
           (java.util.concurrent.atomic AtomicReference)))

(def ^ITransientHelper transient-helper
  (reify ITransientHelper
    (editableRoot [this nm am root]
      (let [new-arr (clojure.core/aclone ^objects (.array nm root))]
        (if (== p/non-regular-array-len (alength ^objects new-arr))
          (aset new-arr p/max-branches (aclone (ints (aget ^objects new-arr p/max-branches)))))
        (.node nm (AtomicReference. (Thread/currentThread)) new-arr)))