有没有办法在Common Lisp中更改文档字符串的分隔符?

ˆᵛˆ*_*ˆᵛˆ 0 documentation common-lisp

我有时会将函数调用及其输出的示例放在函数定义的文档字符串中.

(defun js-[] (&rest args)
  "Javascript array literal statement.
  (js-[] 1 2 3)
  > \"[1, 2, 3]\"
  "
  (format nil "[~{~A~^, ~}]" (mapcar #'js-expr args)))
Run Code Online (Sandbox Code Playgroud)

但有时函数的输出是一个字符串.所以我必须在示例输出中转义双引号.这很快就变得单调乏味.

有没有办法将文档字符串分隔符从双引号更改为其他内容,以便我不必继续转义它们?

请注意,有时它比只逃避一次更糟糕:

(defun js-~ (str)
  "Javascript string statement. This is needed so that double quotes are inserted.
  (js-~ \"string\")
  > \"\\\"string\\\"\"
  "
  (format nil "\"~A\"" str))
Run Code Online (Sandbox Code Playgroud)

这里还有一个问题.阅读文档很困难.

sds*_*sds 6

TL; DR

是的,你可以,,你不想这样做.

不,CL只有一种字符串语法

在Common Lisp中表示字符串的唯一方法是使用 Double-Quote".

是的,您可以修改阅读器,以便其他东西表示字符串

例如,假设你想要一个字符串来启动和停止,比如说@.(这是一个普通字符在符号名称很少使用,在对比度%$其通常在执行内部符号中使用.)

设置@from 的属性":

(multiple-value-bind (function non-terminating-p)
    (get-macro-character #\")
  (set-macro-character #\@ function non-terminating-p))
Run Code Online (Sandbox Code Playgroud)

现在:

(read-from-string "@123@")
==>  "123" ; 5
(read-from-string @"123"@)
==> "123" ; 5
Run Code Online (Sandbox Code Playgroud)

不要忘记将输入语法恢复为标准的Common Lisp语法:

(setq *readtable* (copy-readtable nil))
Run Code Online (Sandbox Code Playgroud)

读者.

您可以修改打印机

该标准不要求string使用可修改的标准对象(例如a )的打印.

您可以尝试定义print-object方法:

(defmethod print-object ((o string) (d stream))
  ...)
Run Code Online (Sandbox Code Playgroud)

然而,

不,你不想这样做

代码存在供人们阅读.

更改Lisp语法将使其他人更难阅读您的代码.

它还会混淆您使用的各种工具(编辑器和c).

CL有很多疣,但这不是其中之一;-)

PS.另见documentationdescribe,以及注释语法Sharpsign竖线分号.


Syl*_*ter 5

你可以制作一个读取器宏,它在一个多行字符串中徘徊,如下所示:

(defun hash-slash-reader (stream slash arg)
  (declare (ignore slash arg))
  (loop :with s := (make-string-output-stream)
        :for c := (read-char stream)
        :if (and (eql #\/ c) (eql #\# (peek-char nil stream)))
             :do (read-char stream) (return (get-output-stream-string s))
        :if (eql #\Newline c)
             :do (peek-char t stream)
        :do (princ c s)))

(set-dispatch-macro-character #\# #\/ #'hash-slash-reader)
Run Code Online (Sandbox Code Playgroud)

现在你可以这样做:

(defun js-~ (str)
  #/ --------------------------
  Javascript string statement. 
  This is needed so that double quotes are inserted.

  (js-~ "string")
  > "\"string\""      
  -------------------------- /#
  (format nil "\"~A\"" str))
Run Code Online (Sandbox Code Playgroud)

将添加文档字符串,就像您使用双引号编写它一样.这实际上与更改字符串的分隔符相同!.实际上,它是分隔字符串的一种方法.

这就是为什么你可以在常规的lisp代码中使用它(不推荐使用),而不仅仅是出于文档目的.

使用/作为调度宏的子字符,有助于使其在概念上接近多行注释,但避免被读者完全忽略.