我正在努力熟悉一个大型项目,可能最初是用Allegro Common Lisp编写的。我遇到了这样一段代码:
(load "epilog:lib;compile.lisp")
谁能解释一下这是什么意思吗?也许,如果这有帮助的话,"epolig"是包的名称"lib;compile.lip"是文件"lib/compile.lsp",或者我可以理解。
这是一种标准的做事方式吗?如果是这样的话,这个代码的意图是什么?SBCL不将冒号识别为文件名中的特殊字符,即它报告Couldn't load "epilog:lib;compile.lisp": file does not exist.
逻辑路径名是标准的Common Lisp功能
它不是一个符号,而是一个逻辑路径名。
Common Lisp具有可移植的逻辑路径名功能。其目的是从物理路径名(如/usr/local/lisp/src/epilog/lib/compile.lisp
或lispm:>sources>epilog>lib>compile.lisp.432
)或任何其他类型的路径名中抽象出来(想想Unix、Mac OS X、Windows…)
目的是为您的软件使用一个单一路径名方案和一个单一逻辑文件组织。无论你在哪台机器上,文件在哪里,你所需要的只是从真实的文件组织到逻辑Lisp组织的映射。
历史
这个设施来自于当时有很多不同的操作系统和许多不同的文件(DEC VMS、IBM MVS、Multics、Unix、Lisp Machines、MS-DOS、Mac…)的时代。Lisp Machine是联网的,可以与各种计算机交谈,所以他们学习了所有这些的本地文件语法。在不同的实验室(MIT、Xerox、SRI…)中,网络上有不同的机器和不同的文件服务器。但是Lisp用户想加载epilog:src;load.lisp
,却不记得这些东西到底在哪里:在本地机器上?但是在哪里?在文件服务器上?但是在哪里呢?因此,在每个网络上都有一个注册表,用于将真实文件位置转换为逻辑路径名。
因此,这就像早期的文件"URI"工具——统一资源标识符。
解释的示例
"epilog:lib;compile.lisp"
是逻辑路径名的名称。
epilog
是逻辑主机的名称lib;
是目录路径compile
是文件名lisp
是文件类型
逻辑路径名翻译
您需要的是逻辑路径名和物理路径名之间的转换:
假设我们有一个只有一个翻译规则的逻辑主机EPILOG。此Lisp在/usr/local/sources/epilog/
下的所有文件都在此机器上。所以我们使用一些Unix约定。
CL-USER 40 > (setf (logical-pathname-translations "EPILOG")
`(("**;*.*" "/usr/local/sources/epilog/**/*.*")))
(("**;*.*" "/usr/local/sources/epilog/**/*.*"))
上面只有一个翻译规则:
从EPILOG:**;*.*
到/usr/local/sources/epilog/**/*.*
。
它将逻辑主机及其所有子目录映射到UNIX文件系统中的一个目录。
可以有更多的规则:
- 文档可能在其他地方
- 较大的文件系统上可能有数据文件
- 编译后的fasl文件可能存储在其他地方
- 它可能使用其他物理目录中的逻辑子目录
但是,这里我们只使用一个翻译规则。
解释的示例-第2部分
现在我们可以解析一个逻辑路径名:
CL-USER 41 > (pathname "epilog:lib;compile.lisp")
#P"EPILOG:LIB;COMPILE.LISP"
让我们来描述一下:
CL-USER 42 > (describe *)
#P"EPILOG:LIB;COMPILE.LISP" is a LOGICAL-PATHNAME
HOST "EPILOG"
DEVICE :UNSPECIFIC
DIRECTORY (:ABSOLUTE "LIB")
NAME "COMPILE"
TYPE "LISP"
VERSION NIL
正如您在上面看到的,这些部分已经从我们的字符串中解析出来了。
现在,我们还可以看到逻辑路径名如何转换为真实路径名:
将逻辑路径名转换为物理路径名
CL-USER 43 > (translate-logical-pathname "epilog:code;ui;demo.lisp")
#P"/usr/local/sources/epilog/code/ui/demo.lisp"
因此,现在当您调用(load "epilog:lib;compile.lisp")
时,Lisp将转换逻辑路径名,然后从转换后的物理路径名真正加载文件。我们真正想要的是,用于所有目的的Lisp记住逻辑路径名,而不是物理路径名。例如,当文件有一个名为FOO
的函数时,我们希望Lisp记录函数源的位置,但使用逻辑路径名。通过这种方式,您可以将已编译的文件、已编译的应用程序或Lisp映像移动到另一台计算机,更新翻译,并且它将能够立即找到FOO
的源——如果它在该机器上或该机器可访问的网络上的某个位置可用的话。
逻辑路径名需要进行翻译
要使用逻辑路径名,需要进行如上所述的逻辑路径名转换。它们通常自己存储在翻译文件中。定义翻译,加载它,然后可以使用相应的逻辑路径名编译和加载文件。因此,使用它们的典型软件系统需要相应的翻译。有时需要根据文件路径对其进行编辑,但有时可以在加载翻译文件时计算它们。您需要了解逻辑主机和翻译的定义位置和方式。
历史第2部分
在Symbolics Lisp机器上,有一个站点范围的目录,可以在其中注册系统和逻辑路径名。加载系统可以使用该中心目录查找系统定义,通常还会加载翻译文件。因此,该机制告诉您系统的结构是什么(文件、版本、补丁、系统版本……),并告诉您它的位置(可以分散在几个主机或文件系统上)。
逻辑路径名在较新的软件中使用不多——你有时会在某些较旧的软件中遇到它们,尤其是那些在Lisp机器上运行的软件——在那里,这一功能在整个系统中被广泛使用。