Apa yang saya maksud dengan "fungsi bungkus transparan 'pass-through'" adalah fungsi, sebut saja wrapper
, yang mengembalikan hasil dari meneruskan semua argumennya ke beberapa fungsi lain, sebut saja wrappee
.
Bagaimana ini dilakukan di Emacs Lisp?
NB: Fungsi ideal wrapper
adalah agnostik tentang wrappee
tanda tangan fungsi; yaitu tidak mengetahui jumlah, posisi, nama, dll. dari wrappee
argumen; itu hanya meneruskan semua argumennya wrappee
, seolah-olah wrappee
telah menjadi yang awalnya disebut. (Namun, tidak perlu untuk mengacaukan tumpukan panggilan untuk mengganti panggilan wrapper
dengan panggilan ke wrappee
.)
Saya mengirim sebagian jawaban untuk pertanyaan saya:
(defun wrapper (&rest args) (apply 'wrappee args))
Ini hanya bekerja jika wrappee
ini tidak interaktif. Rupanya, cara fungsi interaktif mendapatkan argumen mereka mewakili "saluran" yang berbeda dari apa yang dicakup oleh (&rest args)
mantera. Yang saya masih perlu, oleh karena itu, adalah equally- wrappee
mitra -agnostic dari (&rest args)
tanda tangan untuk kasus di mana wrappee
merupakan interaktif fungsi.
(Pertanyaan ini dimotivasi oleh masalah yang dijelaskan dalam pertanyaan sebelumnya .)
Dalam hal klarifikasi lebih lanjut tentang apa yang saya minta diperlukan, di bawah ini adalah beberapa contoh, menunjukkan setara dengan Python dan JavaScript dari apa yang saya cari.
Dengan Python beberapa cara standar untuk mengimplementasikan pembungkus seperti itu ditunjukkan di bawah ini:
def wrapper(*args, **kwargs):
return wrappee(*args, **kwargs)
# or
wrapper = lambda *args, **kwargs: wrappee(*args, **kwargs)
(Di sini *args
singkatan dari "semua argumen posisi", dan **kwargs
singkatan dari "semua argumen kata kunci".)
Setara JavaScript akan menjadi seperti ini:
function wrapper () { return wrappee.apply(this, arguments); }
// or
wrapper = function () { return wrappee.apply(this, arguments); }
Sebagai catatan, saya tidak setuju bahwa pertanyaan ini adalah duplikat dari Bagaimana menerapkan mapcar ke suatu fungsi dengan banyak argumen . Saya bingung menjelaskan mengapa, karena kedua pertanyaan itu tampak sangat berbeda bagi saya. Itu seperti ditanya "jelaskan mengapa apel tidak dianggap setara dengan jeruk". Pertanyaan belaka itu sangat gila, sehingga orang ragu akan dapat menemukan jawaban yang akan memuaskan orang yang menanyakannya.
advice
hal - hal yang cukup bermasalah sehingga saya lebih memilih untuk tidak melakukannya. Sebenarnya, motivasi untuk pertanyaan ini adalah mencoba menemukan solusi untuk masalah yang tidak dapat dipecahkan yang saya miliki dengan fungsi yang disarankan ...interactive
spek.Jawaban:
Tentu saja mungkin termasuk
interactive
spesifikasinya. Kita berurusan dengan elisp ! (Lisp adalah bahasa di mana konstruk yang paling penting adalah daftar. Formulir yang bisa dipanggil hanya daftar. Jadi, Anda dapat membangunnya setelah Anda sukai.)Aplikasi: Anda ingin menambahkan beberapa fungsi ke beberapa fungsi secara otomatis. Fungsi yang diperluas harus diberi nama baru sehingga
defadvice
tidak berlaku.Pertama, versi yang sesuai dengan tujuan Anda. Kami mengatur sel fungsi (
fset
) simbolwrapper
dengan semua informasi yang diperlukan dariwrappee
dan menambahkan barang-barang tambahan kami.Ini berfungsi untuk kedua
wrappee
definisi. Versi pertamawrappee
interaktif adalah yang kedua tidak.Tetapi lebih mudah untuk mendefinisikan makro yang membangun fungsi yang diperluas. Dengan itu kita bahkan dapat menentukan nama fungsi sesudahnya. (Bagus untuk versi otomatis.)
Setelah mengeksekusi kode di bawah ini Anda dapat menelepon secara
wrapper-interactive
interaktif danwrapper-non-interactive
non-interaktif.Catatan, sampai sekarang saya belum menemukan cara untuk mentransfer formulir pernyataan tetapi itu juga harus dimungkinkan.
sumber
edebug
. Selain itu, ada fungsi di manainteractive
-spesifikasi jauh lebih besar dari fungsi tubuh. Dalam kasus seperti itu, penulisan ulanginteractive
spesifikasi bisa sangat membosankan. Pertanyaan dan jawabannya membahas prinsip-prinsip yang disyaratkan.Saya harus memecahkan masalah yang sangat mirip
nadvice.el
, jadi di sini ada solusi (yang menggunakan beberapa kode dari nadvice.el):Dibandingkan dengan solusi lain yang diposting sejauh ini, yang satu ini memiliki keuntungan bekerja dengan benar jika
wrappee
didefinisikan ulang dengan spesifikasi interaktif yang berbeda (yaitu tidak akan terus menggunakan spesifikasi yang lama).Tentu saja, jika Anda ingin bungkus Anda benar-benar transparan, Anda bisa melakukannya lebih sederhana:
sumber
advice-eval-interactive-spec
seperti yang disarankan di sini saya dapat membuat spesifikasi interaktif yang sesuai dengan pembungkus dinamis itu.called-interactively-p
kembalit
diwrappee
? Adafuncall-interactively
tapi tidak adaapply-interactively
(apply #'funcall-interactively #'wrappee args)
jika mau. Tetapi Anda hanya boleh melakukannya jika fungsinya disebut secara interaktif, jadi kira-kira seperti itu(apply (if (called-interactively-p 'any) #'funcall-interactively #'funcall) #'wrappee args)
.sunting: Jawaban Tobias lebih bagus dari ini, karena memperoleh bentuk interaktif yang tepat dan dokumentasi dari fungsi yang dibungkus.
Menggabungkan jawaban Aaron Harris dan kjo, Anda dapat menggunakan sesuatu seperti:
Pemakaian:
Sebut pembungkus dengan salah satu dari:
M-x
wrapper-func
sumber