Чи можна приєднати створений рядок doc до лямбда?


10

Документи Emacs кажуть, що коли рядок doc поміщена всередину lambdaабо defun"зберігається безпосередньо в об'єкті функції". Однак ми можемо змінити документи названих функцій, як це:

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

Але ця ж хитрість не працює з лямбдами. Чи є спосіб додати документацію до лямбда? Або якось динамічно генерувати doc-string literal?

Для уточнення уявіть таку ситуацію:

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

Я хотів би, щоб у лямбда був рядок doc, в якому згадуються значення fooі bar.

Відповіді:


12

Ну а лямбда може мати регулярні доктрини, як і будь-яке інше визначення функції:

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

Таким чином, ви можете використовувати:

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

Чому ви хочете docstring про анонімну функцію - це ще одне питання, яке може вплинути на ваш підхід.

Наприклад, якщо ви плануєте прив’язати його до ключа і хочете C-h kвідобразити цю допомогу, ви можете використовувати цей підхід, але, звичайно, допомога все одно відображатиме сам об’єкт функції (включена докстринга), що не так чудовий; проте , ви могли б зробити це , і ви б (і) побачити красиво відформатований варіант:

(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))))

Однак ви можете скористатися символом. Ви можете з’єднати анонімну функцію з безперервним символом і не турбуватися про те, щоб вона конфліктувала з будь-якими іншими символами з тим самим іменем. Це робить довідку чистішою, оскільки вона відображатиме ім'я символу, а не об’єкт функції. У цьому випадку у нас є можливість передавати docstring до, defaliasа не вставляти його у лямбда-форму.

(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))))

або (і це майже те саме), ви можете захопити безперебійний символ і встановити властивість символу безпосередньо, відповідно до вашого оригінального коду:

(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)))))

В якості примітки, майте в вигляді , що ця функція тільки буде підсумовування випускати палітурки значення fooі , barякщо ви використовуєте lexical-binding: tдля вашої бібліотеки. Якщо foo та bar є динамічно пов'язаними, створені мною створені документації, швидше за все, не будуть точними під час виконання. Однак ми можемо задовольнити ситуацію за допомогою динамічних доктрингів. Інформаційний вузол (elisp) Accessing Documentationговорить про documentation-property:

Якщо значення властивості не є "нульовим", не є рядком і не посилається на текст у файлі, воно оцінюється як вираз Lisp для отримання рядка.

Отже, з будь-яким із підходів, що базуються на символах, ми можемо процитувати форму документації, щоб оцінити її під час виклику:

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

13

У Emacs-25 є нова функція саме для цієї мети:

(let ((foo 1)
      (bar 2))
  (lambda ()
    (:documentation (format "Return the sum of %d and %d." foo bar))
    (+ foo bar)))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.