J'ai du code qui teste l'arité d'une fonction. Je l'utilise pour déterminer si des arguments facultatifs ajoutés dans des versions récentes d'un package sont présents. Il appelle subr-arity
des fonctions intégrées et analyse l'arglist des objets bytecode et des 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)))
))
Cela a bien fonctionné jusqu'à Emacs 23. Dans Emacs 24.3 sur Ubuntu 14.04, cela fonctionne bien pour certaines fonctions, mais pas pour d'autres.
(function-argspec 'revert-buffer)
(&optional ignore-auto noconfirm preserve-modes)
(require 'vc)
vc
(function-argspec 'vc-print-log-internal)
1283
Évidemment, le format du bytecode a changé d'une manière qui n'est pas reflétée dans le manuel .
(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)]
Comment accéder de manière fiable à la liste d'arguments d'un objet bytecode? Tout en sachant que l'arité ferait l'affaire, je me fiche des noms des arguments. Plus précisément, je veux savoir combien d'arguments sont obligatoires et combien d'arguments sont facultatifs, ou en d'autres termes, je veux les mêmes informations que j'obtiens subr-arity
. Bien sûr, mon code doit gérer à la fois l'ancien et le nouveau bytecode, j'ai donc besoin de savoir non seulement où creuser, mais aussi quand creuser où.
function-argspec
fonction quelque part, y compris les fonctions de bytecode et les fermetures?
function-argspec
.