common-lisp - 以编程方式加载 Common Lisp 模块
问题描述
几周前我刚开始学习 Common Lisp,如果这是一个明显的问题,我很抱歉。如何以编程方式加载模块?我有一个“任务”目录,每个都是 Lisp 程序,并且想导入每个并运行它们都包含的特定功能。
我找到了一种遍历目录的方法(通过UIOP:DIRECTORY-FILES
)。但是我一直在试图找出一种将模块“作为”特定名称加载的方法,就像在 Python 中一样。这将允许我load "module-1.lisp" as mod
然后load "module-2.lisp" as mod
循环。
伪代码:
for path in directory
(load path as mod)
(mod:function)
如果有更好的方法来实现我想要做的事情,请随意说!提前感谢您的帮助!
解决方案
包和系统的快速总结
“加载为”在 Common Lisp 中没有意义,因为加载与定义新系统或包不同。在 Python 中,文件是模块等,但在 Lisp 中不是。
Lisp 有一个包的概念,它们是命名空间。它们用于组织符号(符号是一等值)。换句话说,他们使用、导出或可能来自其他包的影子符号,仅此而已。当您评估 时(in-package pack)
,您可以直接写入所有可访问的符号pack
,例如my-fun
,否则您需要完全限定符号,例如some-package:their-func
。有一些扩展允许您导入具有不同名称的包,但这不是标准的(请参阅https://github.com/phoe/trivial-package-local-nicknames)
加载 Lisp 脚本不一定与定义包相同,它取决于文件中的内容(如果它是defpackage
表单)。
当您想在 Lisp 中组织源代码时,您可以使用ASDF定义一个系统。一个系统列出了它的所有依赖关系、它的组件(文件)以及它们的组件之间的依赖关系。这就是您描述文件应按哪些顺序加载、编译、测试等的方式。
包和系统是独立的,但在小型系统中,您通常具有相同的系统名称和它定义的唯一包。对于较大的系统,可能有多个包。
请参阅21. 大型编程:包和符号。
你的问题
您的每个文件都需要定义一个包,以避免污染单个命名空间,例如:
(defpackage :common-name.01
(:use :cl :utils)
(:export #:run-me))
(in-package :common-name.01)
;; some code
但是,一旦它们全部加载完毕,无论是使用您的方法还是通过定义适当的 ASDF 系统,您都希望能够访问所有RUN-ME
包中的所有功能。
您可以编写一些列出包等的内省代码,但我认为更好的方法是让每个文件都有一种方法来声明它们的RUN-ME
函数应该在您的框架中注册,就像测试框架一样。
例如,在文件的末尾,您可以编写:
(provide-function 'run-me)
这假设例如您的utils
包定义并导出一个名为的函数,该函数provide-function
将值存储在中央注册表中。
例如,在utils.lisp
:
(defpackage :utils
(:use :cl)
(:export #:provide-function
#:run-all))
(in-package :utils)
(defvar *all-interesting-functions* nil)
(defun provide-function (f)
(pushnew f *all-interesting-functions* :test #'eql))
当你想运行所有函数时,你可以遍历这个列表:
(defun run-all ()
(mapcar #'funcall *all-interesting-functions*))
推荐阅读
- sql - SQL:我需要一列根据其他列的值自动更新其值
- plot - 如何为 X 轴创建对数刻度的 ROC 曲线图?
- android - Android 应用程序因配置更改而崩溃
- xml - 如何在 Xpath 1.0 中进行连接?
- android - BroadcastReceiver 和 ACTION_BOND_STATE_CHANGED 在 Android 9.0 中部分工作
- python - 一个 django APIView 中有两个 get 请求
- sql - 用于检查下一行值是否相同或不同的 SQL 查询
- json - 使用本地 JSON 文件导入时找不到模块
- android - MIUI 中 SHOW_ON_LOCK_SCREEN 是什么权限?以及如何以编程方式启用它?
- php - 在 cPanel 上执行 php 脚本