Tengo un código que prueba la aridad de una función. Lo uso para determinar si los argumentos opcionales agregados en las versiones recientes de un paquete están presentes. Se llama subr-arity
a las funciones incorporadas y analiza el arglist de objetos de código de bytes y 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)))
))
Esto ha funcionado bien hasta Emacs 23. En Emacs 24.3 en Ubuntu 14.04, funciona bien para algunas funciones, pero no para otras.
(function-argspec 'revert-buffer)
(&optional ignore-auto noconfirm preserve-modes)
(require 'vc)
vc
(function-argspec 'vc-print-log-internal)
1283
Evidentemente, el formato del código de bytes ha cambiado de una manera que no se refleja en el manual .
(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)]
¿Cómo puedo acceder de manera confiable a la lista de argumentos de un objeto bytecode? Solo sabiendo que el arity funcionaría, no me importan los nombres de los argumentos. Más precisamente, quiero saber cuántos argumentos son obligatorios y cuántos argumentos son opcionales, o en otros términos, quiero la misma información que obtengo subr-arity
. Por supuesto, mi código debe hacer frente tanto al bytecode antiguo como al nuevo, por lo que necesito saber no solo dónde cavar sino también cuándo cavar dónde.
function-argspec
función en algún lugar, incluidas las funciones de bytecode y los cierres?
function-argspec
.