Macros Clojure中常见宏错误的解决方法
基本上,我对宏还是比较陌生的,我正在努力研究如何用Clojure编写宏。问题是我不断地遇到异常错误,很难弄清楚该从哪里继续。所以我真正想知道的是,我是否可以得到调试Clojure宏的方法(或启发式方法)列表 以我正在处理的当前问题为例,我有以下模型:Macros Clojure中常见宏错误的解决方法,macros,clojure,Macros,Clojure,基本上,我对宏还是比较陌生的,我正在努力研究如何用Clojure编写宏。问题是我不断地遇到异常错误,很难弄清楚该从哪里继续。所以我真正想知道的是,我是否可以得到调试Clojure宏的方法(或启发式方法)列表 以我正在处理的当前问题为例,我有以下模型: {:users [:name :email :registered-on] :post [:title :author]} 我想把它转换成以下形式: (do (def new-form-users (cashew.core/new-form "
{:users [:name :email :registered-on]
:post [:title :author]}
我想把它转换成以下形式:
(do (def new-form-users (cashew.core/new-form "/users/new" "Create a new Users"
["name" "email" "registered-on"] ("Name" "Email" "Registered-on")))
(def new-form-post (cashew.core/new-form "/post/new" "Create a new Post"
["title" "author"] ("Title" "Author"))))
为此,我编写了以下宏:
(defmacro gen-create-forms [model]
`(do
~@(for [[entity-kw values] model]
(let [entity-sym (-> entity-kw name capitalize)
fields (vec (map name values))]
`(def ~(symbol (str "new-form-" (name entity-kw))) (new-form ~(str "/" (name entity-kw) "/new") ~(str "Create a new " entity-sym) ~fields ~(map capitalize fields)))))))
但是,当我运行宏时,我得到:
java.lang.String cannot be cast to clojure.lang.IFn
[Thrown class java.lang.ClassCastException]
我试着打电话给macroexpand-1,但我也遇到了同样的错误,我对如何解决这个问题几乎一无所知
他说:“当编译器看到一个宏时,它只是一个返回一些代码的函数,它运行该函数,并替换返回到程序中的代码。”提示我将宏编写为一个函数,它接受我拥有的值并输出我希望它们转换成的结果
因此,这项工作:
(defn gen-create-forms [model]
`(do
~@(for [[entity-kw values] model]
(let [entity-sym (-> entity-kw name capitalize)
fields (vec (map name values))]
`(def ~(symbol (str "new-form-" (name entity-kw))) (new-form ~(str "/" (name entity-kw) "/new") ~(str "Create a new " entity-sym) ~fields ~(map capitalize fields)))))))
(gen-create-forms {:users [:name :email :registered-on]
:post [:title :author]})
(do (def new-form-users (cashew.core/new-form "/users/new" "Create a new Users" ["name" "email" "registered-on"] ("Name" "Email" "Registered-on"))) (def new-form-post (cashew.core/new-form "/post/new" "Create a new Post" ["title" "author"] ("Title" "Author"))))
我不确定我在这里是否正确使用了宏,或者宏是否是解决此问题的正确策略。不过,如果您能提供一些关于编写宏时遇到异常时所做工作的想法,或者提供调试这些异常的良好技术,我们将不胜感激
编辑:米凯拉提醒我这不是一个好例子,但我的问题仍然存在。因此,重申一下,如果在clojure中编写宏时遇到异常情况,您会使用哪些技巧?我个人不会为此使用宏-我建议的替代方法是:
- 避免尝试在名称空间中生成新的符号名称-这可能会变得混乱和复杂李>
- 而是创建一个名为“newforms”的数据结构,其中包含hashmap中的所有表单。您可以使用关键字或字符串作为键,我个人会使用“:users”这样的关键字,因为您已经在模型数据结构中使用了这种方法
- 使用以模型为参数的函数生成“新表单”,并根据需要为模型中的每个表单调用
)(cashew.core/new-form…
- 当您想要访问特定表单时,您可以执行
或类似操作,从hashmap中读取相应的表单(新表单:用户)