Ich habe Code, der die Arität einer Funktion testet. Ich verwende es, um festzustellen, ob optionale Argumente vorhanden sind, die in neueren Versionen eines Pakets hinzugefügt wurden. Es subr-arity
erfordert integrierte Funktionen und analysiert die Liste der Bytecode-Objekte und Lambdas.
(defun function-argspec (func)
(if (symbolp func) (setq func (indirect-function func)))
(cond
((byte-code-function-p func)
(aref func 0))
((and (consp func)
(eq (car func) 'lambda)
(consp (cdr func)))
(car (cdr func)))
))
Dies hat bis Emacs 23 gut funktioniert. In Emacs 24.3 unter Ubuntu 14.04 funktioniert es für einige Funktionen gut, für andere jedoch nicht.
(function-argspec 'revert-buffer)
(&optional ignore-auto noconfirm preserve-modes)
(require 'vc)
vc
(function-argspec 'vc-print-log-internal)
1283
Offensichtlich hat sich das Bytecode-Format auf eine Weise geändert, die im Handbuch nicht berücksichtigt wird .
(symbol-function 'vc-print-log-internal)
#[1283 \301\211\302\301\211\203\211@\303!\203\304\262A\266\202\202\210\203'\305>\202*\306>??\262\2036\307\2027\310\262\311
\312\313\314\315\316
$\317"\320\321%\312\322\323\315\316#\324"\325\326%\312\327\330\315\316!\331"\332\333%\312\334\335\315\316%\336"\325\337%&\262\207 [vc-log-short-style nil *vc-change-log* file-directory-p t directory file short long vc-log-internal-common make-byte-code 1028 \304\305\303\301\205\300\302&\207 vconcat vector [vc-call-backend print-log] 12
(fn BK BUF TYPE-ARG FILES-ARG) 771 \303\300\301\302$\207 [vc-print-log-setup-buttons] 8
(fn BK FILES-ARG RET) 257 \301\302\300#\207 [vc-call-backend show-log-entry] 5
(fn BK) 514 \305\300\301\302\303\304%\207 [vc-print-log-internal]
(fn IGNORE-AUTO NOCONFIRM)] 28
(fn BACKEND FILES WORKING-REVISION &optional IS-START-REVISION LIMIT)]
Wie kann ich zuverlässig auf die Argumentliste eines Bytecode-Objekts zugreifen? Nur zu wissen, dass die Arität ausreichen würde, interessieren mich die Argumentnamen nicht. Genauer gesagt möchte ich wissen, wie viele Argumente obligatorisch und wie viele Argumente optional sind, oder mit anderen Worten, ich möchte dieselben Informationen, von denen ich erhalte subr-arity
. Natürlich muss mein Code sowohl mit Bytecode im alten als auch im neuen Stil umgehen, daher muss ich nicht nur wissen, wo ich graben muss, sondern auch, wann ich wo graben muss.
function-argspec
irgendwo eine endgültige Version Ihrer Funktion, einschließlich Bytecode-Funktionen und Schließungen?
function-argspec
.