Skip to content

Instantly share code, notes, and snippets.

@petterik
Last active May 4, 2017 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save petterik/28c2fff796edbf4aa12e0e043e9342b0 to your computer and use it in GitHub Desktop.
Save petterik/28c2fff796edbf4aa12e0e043e9342b0 to your computer and use it in GitHub Desktop.
om-ui with defs for specified locals
(defmacro with-defs
"Takes a seq of symbols which will be called with def for generated symbols.
These symbols will be replaced in the body with the generated symbols
Examples:
(let [a 1] (macroexpand '(with-defs [a] [a]))) ;; => (do (def a_60267 a) [a_60267])
(let [a 1] (with-defs [a] [a])) ;; => [1]"
[vars & body]
{:pre [(every? symbol? vars)]}
(let [syms (into {} (map (juxt identity #(gensym (str (name %) "_")))) vars)
defs (map (fn [[sym gen]]
`(def ~gen ~sym))
syms)]
`(do
~@defs
~@(walk/postwalk-replace syms body))))
(defmacro om-ui
"om.next/ui for .clj can't close over local vars, so for .clj, we'll define the vars with def
and replace the vars in the body passed to om.next/ui"
[vars & ui-body]
(if (boolean (:ns &env))
`(om/ui ~@ui-body)
`(with-defs ~vars (om/ui ~@ui-body))))
(comment
(let [foo 1
component (om-ui [foo]
Object
(render [this] foo))]
(.render ((om/factory component) {}))) ;; => 1
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment