生成されたドキュメント文字列をラムダに添付することは可能ですか?


10

Emacsのドキュメントは、ドキュメント文字列が中に置かれるlambdadefun、「関数オブジェクトに直接保存される」と述べています。ただし、次のように名前付き関数のドキュメントを変更できます。

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

しかし、同じトリックはラムダでは機能しません。ラムダにドキュメントを追加する方法はありますか?または、どういうわけか動的にドキュメント文字列リテラルを生成しますか?

明確にするために、次の状況を想像してください。

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

ラムダにfooおよびの値を説明するドキュメント文字列が欲しいbarです。

回答:


12

ラムダは他の関数定義と同じように通常のdocstringを持つことができます:

(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そのヘルプを表示したい場合は、このアプローチを使用できますが、もちろん、ヘルプは関数オブジェクト自体(docstringを含む)も表示しますが、そうではありません。すごい; それにもかかわらず、あなたはこれを行うことができ、あなたはでしょう(も)うまくフォーマットのバージョンを参照してください。

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

ただし、記号を使用することもできます。無名関数をインターンされていないシンボルとペアにすることができ、同じ名前の他のシンボルと競合することを心配する必要はありません。これにより、関数オブジェクトではなくシンボル名が表示されるため、ヘルプがわかりやすくなります。この例defaliasでは、ラムダフォームに埋め込む代わりに、docstringを渡すオプションがあります。

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

または(これはほとんど同じことです)、元のコードに従って、インターンされていないシンボルをキャプチャして、symbolプロパティを直接設定できます。

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

注意点として、この関数はされていることを知っておくだけのためのletバインド値を合計することになるだろうfoobar、あなたが使用している場合lexical-binding: t、あなたのライブラリーのために。fooとbarが動的にバインドされている場合、私が生成したdocstringは実行時に正確ではない可能性があります。ただし、動的な docstring を使用すると、実際にその状況に対応できます。情報ノードに(elisp) Accessing Documentationよるとdocumentation-property

プロパティ値が「nil」ではなく、文字列ではなく、ファイル内のテキストを参照しない場合、文字列を取得するために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)))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.