Đánh giá docstring trong macro
Các macro như defun(hoặc defmacrochính nó) có một docstringđối số tùy chọn , nhưng vì chúng là macro chứ không phải hàm nên docstringkhông được đánh giá, mà được coi là nguyên trạng.
Tôi cần docstringđược đánh giá để thay vì những thứ như thế này -
"does a, then b, then c" ; b is hardcoded
Tôi có thể đặt một cái gì đó như thế này thay thế -
(concat "does a, then " (getenv "<some-shell-variable>") " , then c") ; b isn't hardcoded
Có thể làm điều này mà không cần phải chỉnh sửa các định nghĩa của defunvà defmacrokhông?
Bằng cách tinh chỉnh, ý tôi không phải là ghi đè các định nghĩa, mà là viết các macro mới như prefix-defunvà prefix-defmacrodựa trên các định nghĩa hiện có của defunvà demacro, ngoại trừ, chuỗi docstring được đánh giá bằng cách thay thế tất cả các trường hợp của docstringbằng (eval docstring).
Trả lời
Bạn có thể đặt chuỗi doc của bất kỳ hàm, biến hoặc khuôn mặt nào thành bất kỳ chuỗi nào bạn muốn, cho dù (được tạo động hay không).
Đối với một hàm foo, hãy đặt chuỗi ký hiệu bạn muốn foolàm giá trị của thuộc tính 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.
Điều tương tự đối với defvar hoặc defcustom - sử dụng thuộc tính biểu tượng 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.
Xem hướng dẫn sử dụng Elisp, Khái niệm cơ bản về Tài liệu về nút và các tiêu đề con của nó.
Điều tương tự cho defface- sử dụng thuộc tính biểu tượng variable-documentation. Nhưng deffaceyêu cầu một chuỗi doc. Tuy nhiên, bạn có thể thay đổi nó một cách linh động, như bạn có thể làm đối với một hàm hoặc biến.
(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...)
Đây thực sự là một bản sao của Có thể đính kèm chuỗi doc đã tạo vào lambda không? ngoại trừ câu hỏi đó rất định lambdahướng, và vì vậy câu trả lời của Stefan không chỉ ra rằng bạn có thể làm điều tương tự với defun.
Nếu bạn cần docstring là eval'd theo yêu cầu (tức là bất cứ khi nào bạn yêu cầu), bạn cũng có thể làm điều đó, nhưng dường như không phải với :documentation. Tham khảo câu trả lời của tôi cho câu hỏi trước đó để biết một số tùy chọn để thực hiện điều đó.