elisp - 变异 elisp 函数

标签 elisp

如何定义 mutator elisp 函数?也就是说,如何将参数发送到 elisp 函数,这些参数可以在函数内部修改以在函数外部使用(类似于 C++ 中的非常量引用变量或指针)?例如,假设我有一个函数 foo 定义如下

(defun foo (a b c d)
  ;do some stuff to b, c, and d
        .
        .
        .
  )

我可能想这样调用它

(defun bar (x)
  (let ((a) (b) (c) (y))
  .
  .
  .
        ;a, b and c are nil at this point
        (foo x a b c)
        (setq y (some-other-function-of a b c x and-other-variables))
  .
  .
  .
)) ... ) 
  y)

我知道我可以将某个函数本地的所有参数放入一个大的旧列表中,在函数末尾评估该列表,然后从设置为该函数的返回值的其他列表中获取这些变量(内容列表),即

(setq return-list (foo read-only-x read-only-y))
(setq v_1 (car return-list))
(setq v_2 (cadr return-list))
            .
            .

但是还有更好的方法吗?到目前为止,我在尝试解决这个问题时所完成的就是退出函数,其变量与传入的变量没有什么不同

至于为什么我希望能够做到这一点,我只是尝试重构一些大函数 F,以便与一些可命名概念 c 相关的所有表达式集合都存在于它们自己的小模块 c_1、c_2、c_3 中。 ..c_n 我可以从 F 内部调用我需要更新的任何参数。也就是说,我希望 F 看起来像:

(defun F ( ... )
  (let ((a_1) (a_2) ... )
    (c_1 a_1 ... a_m)
    (c_2 a_h ... a_i)
     .
     .
     .
    (c_n a_j ... a_k)
     .
     .
     .
 ))...))

最佳答案

我能想到的两种方法:

  • 将“函数” foo 设为宏而不是函数(如果可能)
  • 将新创建的 cons(或多个)传递到函数中,并通过 setcar/setcdr 替换其中的 car 和 cdr

如果函数太复杂,您还可以结合使用这两种方法 - 使用宏 foo 创建 a 和 b 的 cons 并使用该 cons 调用函数 foo0,然后再次解压 car 和 cdr。

如果您需要超过 2 个参数,只需使用多个 cons 作为参数即可。

关于elisp - 变异 elisp 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17379385/

相关文章:

emacs - 如何在 Emacs 中为特定项目(Projectile)设置主题

Emacs 中类似 Eclipse 的行注释

Emacs:删除表达式之间的空格

Lisp:引用符号值列表

emacs - Emacs 中 forward-word/backward-word 的任意字符

lisp - Elisp 中各种形式的循环和迭代

emacs - 评估 dir locals 中的值

emacs - 通过 cl 函数传递回调

emacs - 如何在 Emacs 中定义整行注释语法?

Emacs 口齿不清 : "Fall through" type for defcustom.