今天在我的 Mac 上试用 Lisp,我发现以下内容有点令人迷惑:
$ sbcl
This is SBCL 1.4.14, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* (directory "*")
NIL
* (directory "*.*")
(#P"/private/tmp/sbcl/quicklisp.lisp" #P"/private/tmp/sbcl/test1.lisp"
#P"/private/tmp/sbcl/test2.lisp")
Run Code Online (Sandbox Code Playgroud)
在 macOS、Linux、FreeBSD 上,可能还有大多数其他类 UNIX 系统,*代表所有文件。我只见过*.*在 DOS 和 Windows 上使用过。
根据directory描述,通配符依赖于实现。那么,SBCL 在上述操作系统上使用的约定究竟是什么?我怎么知道这个?SBCL 的手册没有描述这一点。即使在上述三个操作系统之间也会有所不同吗?
SBCL消息来源有这样的评论:
Run Code Online (Sandbox Code Playgroud);;; FIXME: the below shouldn't really be here, but in documentation ;;; (chapter 19 makes a lot of requirements for documenting ;;; implementation-dependent decisions), but anyway it's probably not ;;; what we currently do. ;;; ;;; Unix namestrings have the following format: ;;; ;;; namestring := [ directory ] [ file [ type [ version ]]] ;;; directory := [ "/" ] { file "/" }* ;;; file := [^/]* ;;; type := "." [^/.]* ;;; version := "." ([0-9]+ | "*") ;;; ;;; Note: this grammar is ambiguous. The string foo.bar.5 can be ;;; parsed as either just the file specified or as specifying the ;;; file, type, and version. Therefore, we use the following rules ;;; when confronted with an ambiguous file.type.version string: ;;; ;;; - If the first character is a dot, it's part of the file. It is not ;;; considered a dot in the following rules. ;;; ;;; - Otherwise, the last dot separates the file and the type. ;;; ;;; Wildcard characters: ;;; ;;; If the directory, file, type components contain any of the ;;; following characters, it is considered part of a wildcard pattern ;;; and has the following meaning. ;;; ;;; ? - matches any one character ;;; * - matches any zero or more characters. ;;; [abc] - matches any of a, b, or c. ;;; {str1,str2,...,strn} - matches any of str1, str2, ..., or strn. ;;; (FIXME: no it doesn't) ;;; ;;; Any of these special characters can be preceded by an escape ;;; character to cause it to be treated as a regular character.
它说“但无论如何,这可能不是我们目前所做的”,但我不确定这是否意味着该评论对于当前版本或其他版本可能不准确。我假设至少通配符部分足够正确。
这里重要的部分是目录、文件和类型组件都是分开考虑的,因此文件名和扩展名(也称为类型组件)必须有一个单独的通配符,并用点来分隔它们。
该评论将这些称为“Unix 名称字符串”,但我认为这适用于所有平台。