Có thể đính kèm chuỗi doc được tạo vào lambda không?


10

Các tài liệu của Emacs nói rằng khi chuỗi doc được đặt bên trong lambdahoặc defunnó được lưu trữ trực tiếp trong hàm đối tượng hàm. Tuy nhiên, chúng ta có thể thay đổi tài liệu của các hàm được đặt tên như thế này:

(put 'my-function-name 'function-documentation "Blah.")

Nhưng thủ thuật tương tự không hoạt động với lambdas. Có cách nào để thêm tài liệu vào lambda không? Hoặc bằng cách nào đó tự động tạo ra chuỗi doc-chuỗi?

Để làm rõ, hãy tưởng tượng tình huống sau đây:

(let ((foo 1)
      (bar 2))
  (lambda ()
    (+ foo bar)))

Tôi muốn lambda có một chuỗi doc đề cập đến các giá trị foobar.

Câu trả lời:


12

Vâng lambdas có thể có các tài liệu thông thường giống như bất kỳ định nghĩa chức năng khác:

(lambda ()
   "I'm a docstring!"
   (+ foo bar))

Vì vậy, bạn có thể sử dụng:

(let ((foo 1)
      (bar 2))
  `(lambda ()
     ,(format "Function which sums foo=%s and bar=%s" foo bar)
     (+ foo bar)))

Tại sao bạn muốn một chuỗi doc trên một hàm ẩn danh là một câu hỏi khác, điều này có thể ảnh hưởng đến cách tiếp cận bạn thực hiện.

Chẳng hạn, nếu bạn dự định ràng buộc nó với một khóa và bạn muốn C-h khiển thị trợ giúp đó, bạn có thể sử dụng phương pháp này, nhưng tất nhiên trợ giúp vẫn sẽ hiển thị chính đối tượng chức năng (bao gồm cả chuỗi) tuyệt quá; tuy nhiên bạn có thể làm điều này và bạn sẽ (cũng) thấy phiên bản được định dạng độc đáo:

(global-set-key
 (kbd "C-c a")
 (let ((foo 1)
       (bar 2))
   `(lambda ()
      ,(format "Function which sums foo=%s and bar=%s" foo bar)
      (interactive)
      (+ foo bar))))

Bạn có thể thích sử dụng một biểu tượng, tuy nhiên. Bạn có thể ghép một chức năng ẩn danh với một uninterned biểu tượng, và không phải lo lắng về nó mâu thuẫn với bất kỳ biểu tượng khác cùng tên. Điều này làm cho trợ giúp sạch hơn, vì nó sẽ hiển thị tên biểu tượng chứ không phải là đối tượng chức năng. Trong trường hợp này, chúng ta có tùy chọn chuyển chuỗi doc defaliasthay vì nhúng nó ở dạng lambda.

(global-set-key
 (kbd "C-c a")
 (let ((foo 1)
       (bar 2))
   (defalias (make-symbol "a-foo-bar-function")
     (lambda ()
       (interactive)
       (+ foo bar))
     (format "Function which sums foo=%s and bar=%s" foo bar))))

hoặc (và điều này rất giống với điều đó) bạn có thể chụp biểu tượng không liên kết và đặt thuộc tính biểu tượng trực tiếp, theo mã gốc của bạn:

(global-set-key
 (kbd "C-c a")
 (let ((foo 1)
       (bar 2)
       (sym (make-symbol "a-foo-bar-function")))
   (put sym 'function-documentation
        (format "Function which sums foo=%s and bar=%s" foo bar))
   (defalias sym
     (lambda ()
       (interactive)
       (+ foo bar)))))

Là một lưu ý phụ, lưu ý rằng chức năng này sẽ chỉ tóm tắt các giá trị giới hạn cho foobarnếu bạn đang sử dụng lexical-binding: tcho thư viện của mình. Nếu foo và thanh bị ràng buộc động, các tài liệu tôi tạo ra rất có thể không chính xác vào thời gian chạy. Chúng tôi thực sự có thể phục vụ cho tình huống đó với các tài liệu năng động , mặc dù. Nút thông tin (elisp) Accessing Documentationnói về documentation-property:

Nếu giá trị thuộc tính không phải là 'nil', không phải là một chuỗi và không tham chiếu đến văn bản trong một tệp, thì nó được đánh giá là biểu thức Lisp để có được một chuỗi.

Vì vậy, với bất kỳ cách tiếp cận dựa trên biểu tượng nào, chúng tôi có thể trích dẫn biểu mẫu tài liệu để đánh giá nó tại thời điểm cuộc gọi:

(defalias (make-symbol "a-foo-bar-function")
   (lambda ()
     (interactive)
     (+ foo bar))
   '(format "Function which sums foo=%s and bar=%s" foo bar))

13

Trong Emacs-25, có một tính năng mới chính xác cho mục đích đó:

(let ((foo 1)
      (bar 2))
  (lambda ()
    (:documentation (format "Return the sum of %d and %d." foo bar))
    (+ foo bar)))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.