Saya memiliki kode yang menguji arity dari suatu fungsi. Saya menggunakannya untuk menentukan apakah ada argumen opsional yang ditambahkan dalam versi terbaru dari sebuah paket. Ini membutuhkan subr-arity
fungsi bawaan dan mem-parsing daftar objek bytecode dan 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)))
))
Ini telah bekerja dengan baik hingga Emacs 23. Di Emacs 24.3 pada Ubuntu 14.04, ini berfungsi dengan baik untuk beberapa fungsi, tetapi tidak untuk yang lain.
(function-argspec 'revert-buffer)
(&optional ignore-auto noconfirm preserve-modes)
(require 'vc)
vc
(function-argspec 'vc-print-log-internal)
1283
Jelas format bytecode telah berubah dengan cara yang tidak tercermin dalam 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)]
Bagaimana saya bisa secara andal mengakses daftar argumen objek bytecode? Hanya mengetahui arity akan dilakukan, saya tidak peduli dengan nama argumen. Lebih tepatnya, saya ingin tahu berapa banyak argumen yang wajib dan berapa banyak argumen yang opsional, atau dalam istilah lain, saya ingin informasi yang sama yang saya dapatkan subr-arity
. Tentu saja kode saya harus mengatasi bytecode gaya lama dan gaya baru, jadi saya perlu tahu tidak hanya di mana menggali tetapi juga kapan harus menggali di mana.
function-argspec
.function-argspec
fungsi Anda di suatu tempat, termasuk fungsi bytecode dan penutupan?Jawaban:
Sunting: Woo! Saya menemukan fungsi yang akan mengambil daftar argumen normal, atau versi integer dan mengembalikan sedikit tanda tangan:
byte-compile-arglist-signature
di bytecomp.el!Jawaban awal:
Saya harap orang lain dapat berpura-pura apakah ini didokumentasikan atau tidak, tetapi inilah yang saya pelajari dengan membaca
exec_byte_code
bytecode.c di sumber Emacs.Angka yang Anda lihat digunakan untuk menghitung argspec ketika kode byte sebenarnya dijalankan, saya menganggap ini untuk kinerja, itu sebenarnya cukup pintar.
Saya menulis kode ini untuk menunjukkan kepada Anda bagaimana menghitung arity dari suatu fungsi mengingat nomor itu:
Kita dapat melihat di sini bahwa jika kita menjalankan
arity-info
dengan 1283 kita mendapatkan yang berikut:yang dapat Anda lihat menggambarkan arity
vc-print-log-internal
sempurna, 5 total args, 3 diperlukan, 2 opsional, tidak memungkinkan & sisanya.sumber
Atas permintaan, inilah implementasi saya dari
function-argspec
danfunction-arity
. Saya menggunakan solusi asli Jordon Biondo untuk bytecode Emacs 24.sumber