do-symbols
和 do-external-symbols
do-symbols
查看一个包中的所有变量、函数和宏
(do-symbols (s (find-package :PACKAGE))
(print s))
(let (symbols)
(do-symbols (s (find-pcakge :PACKAGE))
(push s symbols)
symbols)
(loop for s being the symbols of (find-package :PACKAGE)
collect s)
do-external-symbols
查看外部可以访问的变量、函数和宏
(do-external-symbols (s (find-package :PACKAGE))
(print s))
其他两种方法与 do-symbols
类似。
包的别名
在定义一个包时,给包取个别名会有更好的用户体验。
(defpackage hello-world
(:nicknames :hello-world :hello :hw)
(:export :run
:is
:ok)
...)
载入包后,可以使用一下任意一种方法来调用
(hello-world:run)
(hello:is)
(hw:ok)
有点值得注意的是,不要给包定义过多的别名,否则容易让使用包的人混淆。包的别名应该具有简洁明了。
(defpackage #:iterate
(:nicknames #:iterate #:iter))
(defpackage :cl-ppcre
(:nicknames :cl-ppcre :ppcre)
导入包时可以给包另取个别名(rename-package
):
(asdf:load-system :cl-ppcre)
(defpackage :mypackage
(:use :cl))
(in-package :mypackage)
;; Add nickname :RE to package :CL-PPCRE.
(rename-package :cl-ppcre :cl-ppcre '(re))
;; You can use :RE instead of :CL-PPCRE now.
(re:scan "a" "abc")
rename-package
的函数原型如下
(rename-package package-designator name &optional (nicknames nil))
可能会有这样的疑惑,为什么不直接重命名这个包?事实上,你可以这样做,但是这种做法并不推荐。
;; DO NOT DO THIS!
(rename-package :cl-ppcre :re)
;; ERROR!
(cl-ppcre:scan "a" "abc")
从上面例子你可以看出,如果你直接将包给重命名了,那么你就无法使用原有的包名来进行调用。
包锁(Package locks)
一些包默认会锁定,如 common-lisp
和 sb-ext
。当然,你也可以在你自定义的包中设置锁。加锁之后其他人就无法对包进行改动了。
(asdf:load-system :alexandria)
(rename-package :alexandria :alex)
在sbcl中运行上述代码时,会得到以下错误信息
Lock on package ALEXANDRIA violated when renaming as ALEX while
in package COMMON-LISP-USER.
[Condition of type PACKAGE-LOCKED-ERROR]
See also:
SBCL Manual, Package Locks [:node]
Restarts:
0: [CONTINUE] Ignore the package lock.
1: [IGNORE-ALL] Ignore all package locks in the context of this operation.
2: [UNLOCK-PACKAGE] Unlock the package.
3: [RETRY] Retry SLIME REPL evaluation request.
4: [*ABORT] Return to SLIME's top level.
5: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING {10047A8433}>)
...
Common Lisp 中有一个包可以强制对加锁的包进行修改 cl-package-lock:
(cl-package-locks:without-package-locks
(rename-package :alexandria :alex))