3

在 emacs 23.1 和 24.1 之间的某个地方,接口发生了url-retrieve变化。在 emacs 23.1 中,它看起来像这样:

(url-retrieve URL CALLBACK &optional CBARGS)

在 24.1 版本中,它看起来像这样:

(url-retrieve URL CALLBACK &optional CBARGS SILENT INHIBIT-COOKIES)

我有一个使用此功能的 emacs 包。我想利用 emacs 24.1 上新的SILENT参数,同时保持与不支持它的旧版 emacs 的向后兼容性。

管理此问题的最佳方法是什么?我可以在运行时获取最大数量的参数吗?

4

4 回答 4

5

您可以使用此函数来获取参数列表:

(defun my-get-arglist (obj)
  ;; code taken from disassemble-internal
  (let ((macro 'nil)
        (name 'nil)
        (doc 'nil)
        args)
    (while (symbolp obj)
      (setq name obj
            obj (symbol-function obj)))
    (if (subrp obj)
        (error "Can't disassemble #<subr %s>" name))
    (if (and (listp obj) (eq (car obj) 'autoload))
        (progn
          (load (nth 1 obj))
          (setq obj (symbol-function name))))
    (if (eq (car-safe obj) 'macro)  ;handle macros
        (setq macro t
              obj (cdr obj)))
    (if (and (listp obj) (eq (car obj) 'byte-code))
        (setq obj (list 'lambda nil obj)))
    (if (and (listp obj) (not (eq (car obj) 'lambda)))
        (error "not a function"))
    (if (consp obj)
        (if (assq 'byte-code obj)
            nil
          (setq obj (byte-compile obj))))
    (cond ((consp obj)
           (setq obj (cdr obj))     ;throw lambda away
           (setq args (car obj))    ;save arg list
           (setq obj (cdr obj)))
          ((byte-code-function-p obj)
           (setq args (aref obj 0)))
          (t (error "Compilation failed")))
    args))
于 2012-06-20T16:58:35.653 回答
3

您可以检查emacs-major-version并确保它 >= 24。

于 2012-06-20T21:51:27.923 回答
2
(defun try-call-with-more-args (function a b c d)
  (condition-case var
      (progn
        (funcall function a b c d)
        (message "there was no error"))
    (wrong-number-of-arguments (funcall function a b c))))

(try-call-with-more-args #'message "b = %d, c = %d" 1 2 3)

尽管 Trey Jackson 发布的那个更聪明,但它更简单,而且实际上有很好的工作机会,即使你的目标是原生 C 函数:)

于 2012-06-21T00:21:43.137 回答
1

如果它是较旧的 emacs 版本,请围绕较旧的函数编写一个包装器:

(let ((orig-fun #'symbol-name-of-orig-fun))
  (defun symbol-name-of-orig-fun (arglist of new function interface)
    (declare (ignore new function interface))
    (funcall orig-fun arglist of)))

这会生成一个词法闭包,它将旧函数的引用存储在新函数中。我不知道 emacs 方言,但我敢打赌这种模式可以在 emacs 中使用。我每隔一段时间就会在普通的 lisp 中使用它。

于 2012-06-22T01:20:09.950 回答