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
.function-argspec
irgendwo eine endgültige Version Ihrer Funktion, einschließlich Bytecode-Funktionen und Schließungen?Antworten:
Edit: Woo! Ich habe eine Funktion gefunden, die entweder die normale Argumentliste oder die Ganzzahlversion verwendet und eine Art Signatur
byte-compile-arglist-signature
zurückgibt : in bytecomp.el!Erste Antwort:
Ich hoffe, jemand anderes kann sich einschalten, ob dies irgendwo dokumentiert ist oder nicht, aber das habe ich gelernt, indem ich
exec_byte_code
in bytecode.c in der Emacs-Quelle gelesen habe .Die Zahl, die Sie sehen, wird verwendet, um die Argspec zu berechnen, wenn der Bytecode tatsächlich ausgeführt wird. Ich gehe davon aus, dass dies für die Leistung ziemlich clever ist.
Ich habe diesen Code geschrieben, um Ihnen zu zeigen, wie Sie die Arität einer Funktion mit dieser Zahl berechnen können:
Wir können hier sehen, dass wir
arity-info
mit 1283 Folgendes erhalten:Was Sie sehen können, beschreibt die Arität von
vc-print-log-internal
perfekt, 5 Gesamtargumente, 3 erforderlich, 2 optional, erlaubt & ruhen nicht.quelle
Auf Anfrage hier meine Implementierung von
function-argspec
undfunction-arity
. Ich habe Jordon Biondos ursprüngliche Lösung für Emacs 24-Bytecode verwendet.quelle