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 whilein 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))
