with-eval-after-load 和 Emacs Lisp 中的评估顺序

with-eval-after-load and order of evaluation in Emacs Lisp

鉴于以下情况:

(with-eval-after-load 'python
  exp1
  )

(with-eval-after-load 'python
  exp2
  )

加载python模式时,exp2是否保证在exp1之后被评估?

如果这两个 with-eval-after-load 在不同的文件中,并且包含 exp2file2 需要包含 exp1file1 怎么办?

简短的回答是,它们的评估顺序与 eval-after-load 表单的评估顺序相同。

如果每个 eval-after-load 只计算一次,那么这就是您需要知道的全部。否则可能会对一些其他细节感兴趣...

如果 'python 还没有被 provided 那么 exp1exp2 的评估顺序(再次)严格是它们的评估顺序评估封闭的 eval-after-load 表格;但更具体地说,它是首先评估它们的顺序。如果这些 eval-after-load 表单中的任何一个被评估 多次 次(但仍然在加载相关库之前),该事实将不会影响 exp1exp2 -- 每个都将被评估一次,并按此顺序。

如果 'python 已经 已经 provided,那么行为是不同的:计算子表达式而不是延迟计算 immediately(即该表单实际上等效于 progn),这意味着如果 eval-after-load 中的任何一个表单被多次求值,它们的子表单也将被求值多次.

How about if those two with-eval-after-load are in different files, and file2 containing exp2 requires file1 containing exp1?

如果先加载file2,然后file2加载file1,则取决于eval-after-load是否在file2 发生在 之前 它加载 file1 (在这种情况下 exp2 首先发生),或者 之后 它加载 file1(在这种情况下 exp1 首先发生)。

所有这一切中的一个小问题是 provide 表达式在库中的位置似乎并不影响事情。出于 eval-after-load 的目的,事情似乎就像 provide 总是在库的最后(通常确实如此)一样,即使事实并非如此。我想这确保了使用特征符号或库名称作为 eval-after-load 参数之间的一致性,但我不确定为什么它以这种方式工作的细节(因为粗略地查看 [=13= 的代码] 建议它可以直接调用 after-load 功能)。

n.b。 with-eval-after-load 是根据 eval-after-load 定义的,这就是我在此答案中使用后者的原因。无论您使用哪个,答案都同样适用。

如果它有所作为,我目前正在使用 Emacs 24.5.1。