ประเมิน docstring ในมาโคร
มาโครเช่นdefun(หรือdefmacroตัวมันเอง) มีdocstringอาร์กิวเมนต์ที่เป็นทางเลือกแต่เนื่องจากเป็นมาโครไม่ใช่ฟังก์ชันdocstringจึงไม่ได้รับการประเมิน แต่ถูกนำมาใช้ตามที่เป็นอยู่
ฉันต้องการที่docstringจะได้รับการประเมินดังนั้นแทนที่จะเป็นแบบนี้ -
"does a, then b, then c" ; b is hardcoded
ฉันใส่อะไรแบบนี้แทนได้ -
(concat "does a, then " (getenv "<some-shell-variable>") " , then c") ; b isn't hardcoded
เป็นไปได้หรือไม่ที่จะทำเช่นนี้โดยไม่ต้องปรับเปลี่ยนคำจำกัดความของdefunและdefmacro?
โดยปรับแต่งผมไม่ได้หมายถึงการเขียนทับคำจำกัดความ แต่เขียนแมโครใหม่เช่นprefix-defunและprefix-defmacroอยู่บนพื้นฐานของคำจำกัดความที่มีอยู่ของdefunและdemacroยกเว้น docstring จะถูกประเมินโดยการเปลี่ยนทุกกรณีด้วยdocstring(eval docstring)
คำตอบ
คุณสามารถตั้งค่าสตริง doc ของฟังก์ชันตัวแปรหรือหันหน้าไปยังสตริงใดก็ได้ที่คุณต้องการไม่ว่าจะ (สร้างแบบไดนามิกหรือไม่ก็ตาม)
สำหรับฟังก์ชันfooให้ใส่สตริงที่คุณต้องการบนสัญลักษณ์fooเป็นค่าคุณสมบัติfunction-documentation:
(defun foo () ; `foo' gets no doc string from this defun.
(interactive)
(message "FOOOOOOOO"))
(put 'foo 'function-documentation "I'm `foo'.") ; Give function `foo' a doc string.
(put 'foo 'function-documentation "I'm NEW `foo' doc.") ; Redefine the doc string.
สิ่งเดียวกันสำหรับ defvar หรือ defcustom - ใช้คุณสมบัติสัญลักษณ์variable-documentation:
(defvar foo 42) ; Variable `foo' has no doc string.
(put 'foo 'variable-documentation "I'm `foo'.") ; Give var `foo' a doc string.
(put 'foo 'variable-documentation "I'm NEW `foo' .") ; Redefine the doc string.
ดูคู่มือ Elisp ข้อมูลพื้นฐานเกี่ยวกับโหนดและโหนดย่อย
สิ่งเดียวกันสำหรับdefface- variable-documentationใช้คุณสมบัติสัญลักษณ์ แต่deffaceต้องใช้สตริงเอกสาร อย่างไรก็ตามคุณสามารถเปลี่ยนแปลงแบบไดนามิกได้ตามที่คุณสามารถทำได้สำหรับฟังก์ชันหรือตัวแปร
(defface foo '((t :foreground "Red")) "0000") ; Doc string "0000".
(put 'foo 'face-documentation "11111") ; Change doc string to "1111".
(defun foo ()
(:documentation (concat "does a, then " (getenv "<some-shell-variable>") " , then c"))
...BODY...)
นี่เป็นการทำซ้ำอย่างมีประสิทธิภาพเป็นไปได้ไหมที่จะแนบสตริงเอกสารที่สร้างกับแลมบ์ดา ยกเว้นคำถามนั้นเป็นคำถามที่เข้าใจง่ายมากlambdaดังนั้นคำตอบของ Stefan จึงไม่ได้ชี้ให้เห็นว่าคุณสามารถทำสิ่งเดียวกันdefunนี้ได้
หากคุณต้องการ docstring ที่จะeval'd ตามความต้องการ (เช่นเวลาที่คุณขอมันทุก) คุณสามารถทำเช่นนั้นเช่นกัน :documentationแต่เห็นได้ชัดว่าไม่ได้อยู่กับ อ้างถึงคำตอบของฉันสำหรับคำถามก่อนหน้านี้สำหรับตัวเลือกบางอย่างในการทำเช่นนั้น