(defun magit-max-args-internal (function)
"Return the maximum number of arguments accepted by FUNCTION."
(if (symbolp function)
(setq function (symbol-function function)))
(if (subrp function)
(let ((max (cdr (subr-arity function))))
(if (eq 'many max)
most-positive-fixnum
max))
(if (eq 'macro (car-safe function))
(setq function (cdr function)))
(let ((arglist (if (byte-code-function-p function)
(aref function 0) ; <--------- format changed
(cadr function))))
(if (memq '&rest arglist)
most-positive-fixnum
(length (remq '&optional arglist))))))
Мне пришлось перекомпилировать magit.el
и обнаружил эту проблему в их коде. Если я правильно следую коду, то они искали арность функции, но вместо этого они получали какое-то «странное» число. Есть идеи, что случилось?
Кроме того, этот пост: Elisp get function arity? предлагает лучшее решение (которое отлично справляется с этой задачей, ответ Андреаса Рёлера Так что я, вероятно, попытаюсь предложить это magit
сопровождающим.
delete-directory
, но, взглянув на них, есть большая вероятность, что у него когда-то было другое количество аргументов, аргументtrash
, означающий перемещение в корзину, вероятно, появится позже, чем сама функция. - person   schedule 02.10.2013delete-directory
изначально имел только то, что сейчас является его первым аргументом. Когда ожидается, что код будет работать для разных версий Emacs, нет ничего необычного в том, чтобы вызывать одну и ту же функцию с другой последовательностью вызовов. Проверка арности - это один из способов попытаться с этим справиться, но иногда количество аргументов не различается, но различаются их типы или значения. Другие подходы: (а) проверка версии Emacs и (б) попытка различных вызовов внутриconditon-case
илиignore-errors
. - person Drew   schedule 02.10.2013subr-arity
. (Возможно, вы имели в виду что-то отличное от встроенного - возможно, вы имели в виду функцию, предоставляемую ванильным кодом?) - person Drew   schedule 02.10.2013help-function-arglist
не лучший вариант? Кажется, прямолинейно? (Чтобы проверить версию Emacs, вам нужно будет вести исторический список функций с их сигнатурами, что кажется менее общим). - person   schedule 02.10.2013help-function-arglist
- плохой вариант. Я только хотел сказать, что (а) да, как вы сказали, нет предопределенной функции Emacs для получения арности, (б) да, как вы сказали, бывают случаи, когда проверка арности полезна, и (в) использование Обработкаcondition-case
иwrong-number-of-arguments
- это еще один способ решения проблемы измененной последовательности вызовов.help-function-arglist
- еще один подход, но он недоступен в некоторых старых версиях Emacs. - person Drew   schedule 02.10.2013magit
. github.com/magit/magit/issues/975 для использования в будущем. - person   schedule 02.10.2013wrong-number-of-arguments
. - person lunaryorn   schedule 02.10.2013(delete-directory "foo" t)
, чтобы попытаться выполнить прямое рекурсивное удаление, и возвращаетесь к ручному рекурсивному удалению на основе вариантаdelete-directory
с одним аргументом, еслиwrong-number-of-arguments
сигнализируется. Что здесь могло пойти не так ?! На самом деле, это гораздо более очевидно и предсказуемо, чем подсчет аргументов, который с гораздо большей вероятностью будет опровергнут необязательными аргументами ... - person lunaryorn   schedule 02.10.2013delete-directory
в том, чтобы удалить каталог. Вызов его дважды в худшем случае вызовет ошибку во втором вызове, потому что каталог больше не существует. Но в любом случае Emacs будет сигнализироватьwrong-number-of-arguments
тогда и только тогда, когда функция была вызвана с неправильным числом аргументов. С выражениемcondition-case
, например в ответе Стефана, будет обнаружена только эта ошибка. Все остальные ошибки распространяются и не вызывают повторного вызоваdelete-directory
. - person lunaryorn   schedule 02.10.2013