In clj/cljr I use the following to get all locally defined variables:
(defmacro get-env
[]
(into {} (for [k (keys &env)]
[`'~k k])))
E.g. (do (defn a [x] (get-env)) (a 5))
would show me that x
is defined to 5
.
When trying the same macro in cljs though, I get this:
{:protocol-inline :protocol-inline, :fn-scope :fn-scope, :locals :locals, :repl-env :repl-env, :ns :ns, :def-emits-var :def-emits-var, :protocol-impl :protocol-impl, :column :column, :root-source-info :root-source-info, :line :line, :context :context}
Is there a way in cljs to extract the locally defined variables?
3 Likes
dnolen
April 4, 2019, 4:06pm
2
You have to look at :locals
in &env
.
1 Like
How? I tried doing (:locals &env)
or similar without success.
dnolen
April 4, 2019, 5:28pm
4
:locals
is a map from symbol to binding info, which is yet another map. You cannot write the same code you would for Clojure. For details of what’s in the binding info map, I suggest reading the ClojureScript analyzer source - it’s not as scary as it sounds. Eventually we may have specs for this stuff.
2 Likes
I’m having a hard time understanding CLJS overall. I tried looking inside (:locals &env)
, (in a clj file I have: (defmacro get-env2 [] (:locals &env))
and I get data back, but it seems like sometimes I get correct data:
cljs-example.core=> (defn a [b] (s/get-env2))
{b {:name b, :binding-form? true, :op :var, :env {:context :expr, :line 1, :column 10}, :column 10, :line 1, :info {:name b, :shadow nil}, :tag nil, :shadow nil}}
But sometimes something else happens:
cljs-example.core=> (defn a [b] (s/get-env2))
#'cljs-example.core/a
cljs-example.core=> (a 5)
{5 {:name 5, :binding-form? true, :op :var, :env {:context :expr, :line 1, :column 10}, :column 10, :line 1, :info {:name 5, :shadow nil}, :tag nil, :shadow nil}}
I understand if I sound whiny, but I feel like I run into weird behaviour all the time using CLJS… I just don’t get it.
2 Likes
Your macro expands to code that will be evaluated. So you see the b
symbol getting replaced my the value you passed as b
, so 5
.
(defmacro get-env2 []
`(quote ~(:locals &env)))
This should work if you just want the pure data.
5 Likes
Thank you! That makes sense! I wonder how I managed to sometimes get data, and sometimes code… Oh well.
system
Closed
October 4, 2019, 11:07pm
8
This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.