clojure - 如何修复这个宏?
问题描述
我正在尝试将我的宏转换为以下扩展:
(re-frame.core/reg-event-db
:some-name
(fn [db [foo bar]]
(assoc db :foo foo :bar bar)
))
到目前为止我有这个
(defmacro db-event
[name params & body]
`(re-frame.core/reg-event-db
~name
(fn [db ~params]
~@body)))
但是当我尝试使用时,这并没有真正起作用
(db-event :some-name [foo bar]
(assoc db :foo foo :bar bar))
我得到以下信息:
------ WARNING - :undeclared-var -----------------------------------------------
Resource: :1:17
Use of undeclared Var vendo.macros/foo
--------------------------------------------------------------------------------
------ WARNING - :undeclared-var -----------------------------------------------
Resource: :1:21
Use of undeclared Var vendo.macros/bar
--------------------------------------------------------------------------------
------ WARNING - :undeclared-var -----------------------------------------------
Resource: :1:33
Use of undeclared Var vendo.macros/db
--------------------------------------------------------------------------------
------ WARNING - :undeclared-var -----------------------------------------------
Resource: :1:41
Use of undeclared Var vendo.macros/foo
--------------------------------------------------------------------------------
------ WARNING - :undeclared-var -----------------------------------------------
Resource: :1:50
Use of undeclared Var vendo.macros/bar
--------------------------------------------------------------------------------
(re-frame.core/reg-event-db {:foo nil, :bar nil} (cljs.core/fn [vendo.macros/my-db nil]))
我该如何解决?
解决方案
首先查看有关宏的此答案。然后慢慢建立起来。
不是这样,因为db
它只在你构造的函数中使用,它不需要是宏调用的参数。
第一次迭代:
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test))
(defn db-event-impl
[[name params]]
(spyx name)
(spyx params)
(let [result `(re-frame.core/reg-event-db
)
]
(spyx-pretty result))
)
(dotest
(db-event-impl (quote [:some-name [foo bar]]))
)
结果:
name => :some-name
params => [foo bar]
result =>
(re-frame.core/reg-event-db)
添加更多代码:
(defn db-event-impl
[[name params]]
(spyx name)
(spyx params)
(let [result `(re-frame.core/reg-event-db
~name
(fn [~'db ; trick to prevent namespacing of `db`
~params ]
(assoc ~'db )
) ) ]
(spyx-pretty result)) )
并得到:
name => :some-name
params => [foo bar]
result =>
(re-frame.core/reg-event-db
:some-name
(clojure.core/fn [db [foo bar]] (clojure.core/assoc db)))
为该assoc
部分添加更多内容:
(let [assoc-form (->list
(apply glue
(quote [assoc db])
(forv [param params]
[(->kw param) param])))
result `(re-frame.core/reg-event-db
~name
(fn [~'db ; trick to prevent namespacing of `db`
~params]
(assoc ~'db)
))]
(spyx assoc-form)
(spyx-pretty result)))
结果:
name => :some-name
params => [foo bar]
assoc-form => (assoc db :foo foo :bar bar)
result =>
(re-frame.core/reg-event-db
:some-name
(clojure.core/fn [db [foo bar]] (clojure.core/assoc db)))
然后把它们放在一起:
(ns tst.demo.core
(:use demo.core tupelo.core tupelo.test))
(defn db-event-impl
[[name params]]
(let [assoc-form (->list
(apply glue
(quote [assoc db])
(forv [param params]
[(->kw param) param])))
result `(re-frame.core/reg-event-db
~name
(fn [~'db ; trick to prevent namespacing of `db`
~params]
~assoc-form))]
result))
(defmacro db-event
[& args]
(db-event-impl args))
(dotest
(let [expected (quote
(re-frame.core/reg-event-db
:some-name
(clojure.core/fn [db [foo bar]]
(assoc db :foo foo :bar bar))))]
(is= expected
(db-event-impl (quote [:some-name [foo bar]])))))
推荐阅读
- javascript - Mongodb:如何通过我的 api 填充我的架构中引用的架构
- c# - Unity 中的 KewordRecognizer:MissingMethodException
- c# - Unity透明视频播放器不显示在设备上?
- html - 使用特殊字符生成的二维码无法在 html 输入中读取
- go - 写入具有多个 goroutine 的互斥映射是否比一个更快?为什么?
- javascript - 日期和时间选择器,禁用未来和过去的日期和时间
- php - 如何使用foreach()将数组中的所有行组合为一个输入?
- filemaker - 选项卡上的新记录按钮有问题?
- android - 无法获取 PageUp/PageDown KeyEvent
- python - 如何使用每个组的不同条件进行 drop_duplicate?