เป็นไปได้หรือไม่ที่จะแนบสตริงเอกสารที่สร้างขึ้นกับแลมบ์ดา?


10

Emacs docs บอกว่าเมื่อมีการวางสตริง doc ไว้ภายในlambdaหรือdefunเป็น“ เก็บไว้ในฟังก์ชันวัตถุ” โดยตรง อย่างไรก็ตามเราสามารถเปลี่ยนเอกสารของฟังก์ชั่นที่มีชื่อดังนี้:

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

แต่เคล็ดลับแบบเดียวกันนั้นใช้ไม่ได้กับลูกแกะ มีวิธีเพิ่มเอกสารในแลมบ์ดาหรือไม่? หรืออย่างใดอย่างหนึ่งสร้างตัวอักษร doc- สตริงแบบไดนามิก?

หากต้องการชี้แจงให้จินตนาการถึงสถานการณ์ต่อไปนี้:

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

ผมอยากแลมบ์ดาที่จะมีสตริง doc ที่กล่าวถึงคุณค่าของและfoobar

คำตอบ:


12

lambdas ก็สามารถมีเอกสารปกติเหมือนนิยามฟังก์ชั่นอื่น ๆ :

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

อย่างไรก็ตามคุณอาจต้องการใช้สัญลักษณ์ คุณสามารถจับคู่ฟังก์ชั่นที่ไม่ระบุชื่อกับuninternedสัญลักษณ์และไม่ต้องกังวลเกี่ยวกับเรื่องความขัดแย้งกับสัญลักษณ์อื่น ๆ ที่มีชื่อเดียวกัน สิ่งนี้จะช่วยให้ตัวทำความสะอาดดีขึ้นเนื่องจากมันจะแสดงชื่อสัญลักษณ์แทนวัตถุฟังก์ชัน ในตัวอย่างนี้เรามีตัวเลือกในการส่ง 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 ถูกผูกไว้แบบไดนามิก docstrings ที่ฉันสร้างขึ้นน่าจะไม่ถูกต้องในเวลาทำงาน เราจริงสามารถให้ความสำคัญกับสถานการณ์ที่มีไดนามิก docstrings แม้ว่า โหนดข้อมูล(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)))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.