Ho un codice che testa l'arità di una funzione. Lo uso per determinare se sono presenti argomenti opzionali aggiunti nelle ultime versioni di un pacchetto. Richiede subr-arity
funzioni integrate e analizza l'arglista di oggetti bytecode e lambda.
(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)))
))
Questo ha funzionato bene fino a Emacs 23. In Emacs 24.3 su Ubuntu 14.04, funziona bene per alcune funzioni, ma non per altre.
(function-argspec 'revert-buffer)
(&optional ignore-auto noconfirm preserve-modes)
(require 'vc)
vc
(function-argspec 'vc-print-log-internal)
1283
Evidentemente il formato del bytecode è cambiato in un modo che non si riflette nel manuale .
(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)]
Come posso accedere in modo affidabile all'elenco degli argomenti di un oggetto bytecode? Solo sapendo che avrebbe fatto l'arità, non mi importa dei nomi degli argomenti. Più precisamente, voglio sapere quanti argomenti sono obbligatori e quanti argomenti sono opzionali o, in altri termini, voglio le stesse informazioni da cui ottengo subr-arity
. Ovviamente il mio codice deve far fronte al bytecode sia vecchio che nuovo, quindi devo sapere non solo dove scavare ma anche quando scavare dove.
function-argspec
funzione da qualche parte, comprese le funzioni bytecode e le chiusure?
function-argspec
.