通过Clojure中的变量将数据传递给宏(脚本)

时间:2017-11-26 19:35:33

标签: clojure macros clojurescript

是否有任何技巧可以直接或使用eval传递数据?

Text = ""
For j = 0 To 1
    If j > 0 Then
        Text = Text & ";"
    End If
    Text = Text & Manager.Grid.Rows(i).Cells(j).Value
Next

1 个答案:

答案 0 :(得分:2)

如果在宏调用之前在命名空间中定义了data var,则可以使用一些命名空间操作函数来按名称解析它的值:

(defmacro pair-defs [data]
  `(do ~@(for [[k v] @(ns-resolve *ns* data)]
           `(def ~k ~v))))

user> (def data [['a 10] ['b 20]])
#'user/data

user> (pair-defs data)
#'user/b

或通过var name处理文字数据和数据:

(defmacro pair-defs [data]
  (let [dt (if (symbol? data) @(ns-resolve *ns* data) data)]
    `(do ~@(for [[k v] dt]
             `(def ~k ~v)))))

将通话扩展为所需的格式:(do (def a 10) (def b 20))

所以解决命名空间val没有像eval这样的肮脏技巧是完全可能的,但我发现它是非常不必要的宏用法。例如,您的任务可以通过普通函数调用轻松替换。

(defn pair-defs1 [data]
  (doseq [[k v] data]
    (intern *ns* k v)))

它适用于任何data序列,无论是本地还是全局,文字或生成