Lisp导出内部符号

时间:2019-09-04 11:02:18

标签: package common-lisp asdf

我正在学习定义一个系统,并制作了一个名为 test 的小型测试包。它的结构如下所示:

test/
  test.asd
  hi.lip
  hito.lisp
  package.lisp

现在在package.lisp文件中,我定义了我的包裹:

(in-package :cl-user)

(defpackage :test
  (:use #:cl)
  (:import-from #:uiop
        #:strcat)
  (:export #:sayhito))

并在test.asd系统中:

(defsystem test
  :name "Testing"
  :components ((:file "package")
           (:file "hi")
           (:file "hito")))

在hi.lisp中,我有一个辅助函数sayhi,但这并不意味着它是外部的:

(in-package :test)

(defun sayhi () "Hi")

以及在hito.lisp中,系统hito的外部功能:

(in-package :test)

(defun sayhito (name)
  (strcat (sayhi) " " name "!"))

我还有一个目录/ home / amir / lisp-link-farm /,在其中放置了所有ASDF的符号链接。然后在我的Lisp初始化文件(.sbclrc)中,将此路径推送到asdf:*central-registry*中:

;;; The following lines added by ql:add-to-init-file:
#-quicklisp
(let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp"
                                   (user-homedir-pathname))))
  (when (probe-file quicklisp-init)
    (load quicklisp-init)))


;; where i am restoring symlinks to systems
(require 'asdf)
(push #p"/home/amir/lisp-link-farm/" asdf:*central-registry*)

现在,当我通过(ql:quickload :test)加载测试系统并将软件包更改为(in-package :test)时,内部帮助函数hi也可以作为外部符号访问!我可以做到:

(sayhi)   ;; -> "Hi"

但是,如果我不更改软件包(因此在REPL中没有(in-package :test)),则试图调用(test:sayhi)的Lisp抱怨sayhi不是软件包测试中的外部符号,而(test:sayhito "Lisp")可以正常工作。 为什么会这样,我在做什么错?任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:3)

否,它不能作为外部符号访问。在编写自己的代码时,您将包更改为有问题的包,这意味着它是您的当前包,并且所有符号解析在内部都是 。就像在特定程序包中编写代码时一样:您可以引用该程序包的所有符号,而无需在该程序包前加注。

请注意,即使您将当前软件包更改为test,引用test:hi(带有单个冒号)也将指示错误。

因此,您没有做错任何事情,只是期望REPL在某种程度上具有除源文件之外的其他程序包解析规则。

答案 1 :(得分:3)

看来您做得还可以。如果导出函数,则可以使用package:functiontest:sayhito)(冒号)进行访问。如果不导出,则仍然可以使用双冒号package::functiontest::sayhi)来访问它。

当您位于包中时,您可以直接键入所有符号(无论是否导出),这就是目标。