【问题标题】:elisp dealing with closureelisp 处理关闭
【发布时间】:2011-11-18 08:25:15
【问题描述】:

我正在尝试编写一个可以生成一组函数的宏,我可以使用这些函数以更有效的方式访问项目目录。如果您查看以下宏,您应该很清楚我要做什么。

(defmacro create-project-cmd (project-name project-dir &optional subdir-list)
  (if (null subdir-list)
      `(fset (intern ,project-name) #'(lambda () (interactive) (dired ,project-dir)))
      `(dolist (dir ,subdir-list)
         (fset (intern (concat ,project-name "-" dir))
               #'(lambda () (interactive) (dired (concat ,project-dir "/" dir)))))))

这里的问题是最后一行中的“dir”应该与 dolist 子句中的“dir”绑定。而且由于elisp中没有闭包,当我调用一个生成的函数时,它会抱怨dir is void。

从代码中可以看出,我伪造了“project-dir”的闭包。对于“dir”,我不能以同样的方式伪造它。尽管 lexical-let 可以让它在这里工作,但我试图避免它,因为它有一些内存问题,而且我不想养成使用它的习惯(也许我在这里太挑剔了)。

我没有很好的方法来处理这个问题。大家有什么好的建议吗?

【问题讨论】:

标签: emacs macros closures elisp


【解决方案1】:

编辑:如果 lexical-let 不存在,像这样的东西怎么样:

(defmacro create-project-cmd (project-name project-dir &optional subdir-list)
  (if (null subdir-list)
      `(fset (intern ,project-name) #'(lambda () (interactive) (dired ,project-dir)))
    (let ((fsets nil))
      (dolist (dir subdir-list)
        (add-to-list
         'fsets
         `(fset (intern (concat ,project-name "-" ,dir))
                #'(lambda () (interactive) (dired (concat ,project-dir "/" ,dir))))))
      `(progn ,@fsets))))

(create-project-cmd "projfoo" "projdir" ("foo" "bar" "baz"))

(symbol-function 'projfoo-bar)
(lambda nil (interactive) (dired (concat "projdir" "/" "bar")))

【讨论】:

  • 感谢您提供的信息,但我已经考虑了所有这些。正如您从代码中看到的那样,我已经使用“project-dir”的宏伪造了闭包。但是对于“dir”,它更难,因为它在宏内部,如果我使用另一个宏调用,它只会传递符号名称而不是值,并且在运行时我无法获取值,我尝试过但失败了。我也在尽量避免使用 lexical-let,因为它有一些内存问题需要作为结果,所以我不想养成使用它的习惯(即使它会在这里工作)。
  • 是的,我确实假设您想在那里使用lexical-let。这个怎么样? ^^
  • 啊,我在想类似的事情,但我完全忘记了 ,@ 运算符。非常感谢。 :)
  • 啊,就是这样。我知道我的答案中有另一个不好的宏。请注意,编译时它不起作用,因为宏扩展发生在编译时。我需要解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-27
相关资源
最近更新 更多