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
.function-argspec
fonction quelque part, y compris les fonctions de bytecode et les fermetures?Réponses:
Edit: Woo! J'ai trouvé une fonction qui prendra soit la liste d'arguments normale, soit la version entière et retournera une sorte de signature:
byte-compile-arglist-signature
dans bytecomp.el!Réponse initiale:
J'espère que quelqu'un d'autre pourra sonner si cela est documenté quelque part mais c'est ce que j'ai appris en lisant l'
exec_byte_code
intérieur de bytecode.c dans la source Emacs.Le nombre que vous voyez est utilisé pour calculer l'argspec lorsque le code d'octet est réellement exécuté, je suppose que pour les performances, c'est en fait assez intelligent.
J'ai écrit ce code pour vous montrer comment calculer l'arité d'une fonction étant donné ce nombre:
Nous pouvons voir ici que si nous exécutons
arity-info
avec 1283, nous obtenons ce qui suit:que vous pouvez voir décrit l'arité de
vc-print-log-internal
parfaitement, 5 arguments totaux, 3 requis, 2 facultatifs, ne permet pas & reste.la source
Sur demande, voici mon implémentation de
function-argspec
etfunction-arity
. J'ai utilisé la solution originale de Jordon Biondo pour le bytecode Emacs 24.la source