【问题标题】:Writing different pieces of code to the compiled (.elc) file, based on different conditions根据不同的条件,将不同的代码段写入已编译的 (.elc) 文件
【发布时间】:2016-02-14 13:15:43
【问题描述】:

我想有条件地将不同的代码段写入我的 elisp 文件 (.elc) 的编译版本,我可以通过函数定义来做到这一点:

(defalias 'my-test
  (eval-when-compile
    (if nil 
      (lambda ()
        (message "True"))
      (lambda ()
        (message "False")))))

通过上面的代码,我可以根据不同的条件为my-test分配不同的匿名函数,并将结果写入编译后的.elc文件。但我想写的是文件范围中的函数调用。像这样:

(eval-when-compile
  (if nil
      (add-to-list 'auto-mode-alist '("\\.gitconfig\\'" . A-mode))
    (add-to-list 'auto-mode-alist '("\\.gitconfig\\'" . B-mode))))

;; or using `when' to either write a call or do nothing:
(eval-when-compile
  (when (not (eq (user-uid) 0))           ; if uid != 0
    (dangerous-call)))

代码在编译时被评估,评估结果只会在编译过程中可用,之后没有任何东西去.elc,因为我没有将它分配给任何东西,但我怎么能真正写if 控件的字节编译结果(这是对add-to-list 函数的调用)到已编译的.elc 文件?在这种情况下,我希望将(add-to-list 'auto-mode-alist '("\\.gitconfig\\'" . B-mode)) 写入.elc 文件。

【问题讨论】:

  • Emacs Lisp 不是我的强项,但你尝试过类似(add-to-list 'auto-mode-alist '("\\.gitconfig\\'" . (eval-when-compile (if nil 'a-mode 'b-mode)))) 的东西吗?
  • @jkiiski 这应该可以工作,但是如果我使用when 而不是if 并且条件变成false,那么就没有什么可以返回并且...。例如,如果我想调用一个函数什么都不做。
  • 您是否引用了电话 ('(add-to-list ...))?
  • 您可以使用像(defmacro define-if (condition form) (if condition `,form)) 这样的宏。它似乎产生与(define-if t (defun f () (interactive))) 相同的字节码。
  • 哦,我忘记了 eval (并且无法编辑)。 (defmacro define-if (condition form) (if (eval condition) `,form)).

标签: emacs lisp elisp


【解决方案1】:

我认为这个问题的答案是宏:如果您编写一个扩展为您想要的代码的宏,然后只需将宏的调用放在顶层,那么宏的扩展将最终在编译文件。

所以:

(defmacro foo ()
  (if <compile-time-condition>
      `(setq ...)
      `(setq ...)))

(foo)

警告:您只能在编译时以您知道的事情为条件:您在 UID 上调度的示例可能不会达到您的预期。

【讨论】:

    【解决方案2】:

    tfb 的回答通常是更好的选择,但对于一次性情况,您可能更愿意这样做

    (if (eval-when-compile (my-test))
        (add-to-list 'auto-mode-alist '("\\.gitconfig\\'" . A-mode))
      (add-to-list 'auto-mode-alist '("\\.gitconfig\\'" . B-mode)))
    

    甚至可以改写成

    (add-to-list 'auto-mode-alist 
                 `("\\.gitconfig\\'"
                 . ,(if (eval-when-compile (my-test)) 'A-mode 'B-mode)))
    

    这依赖于编译器优化,根据常量将(if &lt;constant&gt; a b) 转换为ab

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-08-14
      • 2019-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多