Eu tenho um código que testa a aridade de uma função. Eu o uso para determinar se argumentos opcionais adicionados em versões recentes de um pacote estão presentes. Ele chama subr-arity
funções internas e analisa o arglist de objetos de bytecode e 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)))
))
Isso funcionou bem até o Emacs 23. No Emacs 24.3 no Ubuntu 14.04, ele está funcionando bem para algumas funções, mas não para outras.
(function-argspec 'revert-buffer)
(&optional ignore-auto noconfirm preserve-modes)
(require 'vc)
vc
(function-argspec 'vc-print-log-internal)
1283
Evidentemente, o formato do bytecode mudou de uma maneira que não é refletida no 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)]
Como posso acessar com segurança a lista de argumentos de um objeto de bytecode? Apenas sabendo que a aridade serviria, não me importo com os nomes dos argumentos. Mais precisamente, quero saber quantos argumentos são obrigatórios e quantos argumentos são opcionais ou, em outros termos, quero as mesmas informações que recebo subr-arity
. É claro que meu código deve lidar com os bytecodes do estilo antigo e do novo, então eu preciso saber não apenas onde cavar, mas também quando cavar onde.
function-argspec
função em algum lugar, incluindo funções e fechamentos de bytecode?
function-argspec
.