【问题标题】:Macro with a function definition including set! not working in Clojurescript带有函数定义的宏,包括 set!不在 Clojurescript 中工作
【发布时间】:2015-08-02 22:20:51
【问题描述】:

我正在尝试定义一个应该执行以下操作的宏:

  • 将“变量”与初始值绑定
  • 使用基于变量名称的名称创建 setter 方法

我在 clojure 文件中定义了以下内容:

(defmacro defprop
  [prop-name init-value]
  `(do
    (def ~prop-name ~init-value)
    (def ~(symbol (str prop-name "-other")) ~init-value)
    (defn ~(symbol (str prop-name "-11")) [] (set! ~prop-name 11))
    (defn ~(symbol (str prop-name "-set")) [new-val] (set! ~prop-name new-val))))

当像这样从 clojurescript 调用时(cmacros 是命名空间别名):

(cmacros/defprop production 350)

我对“生产”和“生产-其他”的定义正确,“生产-11”功能有效(并将生产价值设置为 11),但最后一个不起作用。 我在不同的浏览器中遇到不同的错误。 Chrome 显示“Uncaught SyntaxError: Unexpected token .”。 Firefox “SyntaxError: missing ) after 形式参数”。

Firefox 指出的有问题的 javascript 代码如下所示:

cgamemini.core.production_set = (function
  cgamemini$core$production_set(cgamemini.macros.new_val) {
    return cgamemini.core.production = cgamemini.macros.new_val;
  }
);

似乎所有括号都正确,尽管我不是 js 专家。 怎么了?为什么 -11 定义有效但 -set 无效?

【问题讨论】:

    标签: macros clojurescript defn


    【解决方案1】:

    问题是new-val。 Clojure 宏扩展不理解语法,因此它不知道 new-val 应该是一个参数——任何出现在宏扩展中的裸符号都会自动命名为当前命名空间。这就是您在输出中看到cgamemini$core$production_set(cgamemini.macros.new_val) 的原因。您要做的是使用卫生宏语法来指示应该创建一个没有命名空间的新符号,例如

    `(defn ~(symbol (str prop-name "-set")) [new-val#] (set! ~prop-name new-val#))
    

    另一种方法是注入您的符号:

    `(defn ~(symbol (str prop-name "-set")) [~'new-val] (set! ~prop-name ~'new-val))
    

    【讨论】:

      猜你喜欢
      • 2012-01-04
      • 2016-11-05
      • 1970-01-01
      • 1970-01-01
      • 2016-05-10
      • 1970-01-01
      • 1970-01-01
      • 2013-07-31
      • 2016-09-10
      相关资源
      最近更新 更多