【问题标题】:Understanding package loading了解包加载
【发布时间】:2013-11-29 21:26:46
【问题描述】:

(已解决,见 cmets)

最近我一直在研究一个必须与现有服务交互的 API。一切似乎都运行良好,而且我的项目刚刚开始变得足够大,以至于我会看到将东西放入一个包中会带来一些好处。由于这是我在 CL 中的第一个“真正”项目,我想我还没有完全理解这里发生的打包/加载机制。

我的基本问题是我有一堆代码,它们使用宏来生成函数/类,将它们实习到我的包中,然后导出人们最终将用来与 API 交互的某些函数/访问器。如果我像这样单独加载文件:

(load "~/src/lisp/cl-bitcoin/bitcoin.lisp")
(load "~/src/lisp/cl-bitcoin/classes.lisp")
(load "~/src/lisp/cl-bitcoin/functions.lisp")

一切正常。我的宏声明的函数被正确地嵌入和导出,我可以调用它们来与 API 交互。但是,如果我尝试执行以下操作:

(ql:quickload :btc)

Quicklisp 告诉我一切都已正确加载 - 似乎大部分加载过程都按我的预期进行,因为我的所有依赖项都已加载并可供使用。问题是与我的包裹相关的所有内容都不可用。这包括直接从我的 package.lisp 文件中导出的函数。作为参考,这里是我的 .asd 和包文件:

package.lisp

(defpackage #:btc
(:use #:cl)
(:export #:set-connection-parameters
     #:reset-rpc-id
     #:with-connection-parameters
     #:btc-base-err
     #:btc-base-id))

btc.asd

(asdf:defsystem #:btc
:serial t
:depends-on (#:drakma
             #:flexi-streams
             #:cl-json)
:components ((:file "package")
             (:file "bitcoin")
         (:file "classes")
         (:file "functions")))

我觉得我在这里遗漏了一些相当明显的东西 - 我一直在研究 eval-when 和其他相关的加载功能,但无法弄清楚这一点。有人可以向我解释这里发生了什么吗?

感谢您的帮助。

编辑:这是我的 REPL 的样子:

; SLIME 2011-02-04
CL-USER> (ql:quickload :btc)
To load "btc":
  Load 1 ASDF system:
    btc
; Loading "btc"
..
(:BTC)
CL-USER> (btc:help "getinfo")
Invoking restart: Return to SLIME's top level.
; Evaluation aborted on #<SIMPLE-ERROR #x30200175DF0D>.
CL-USER> ; Reader error: No external symbol named "HELP" in package #<Package "BTC"> .
; No value
CL-USER> (load "/Users/jordan/src/lisp/cl-bitcoin/bitcoin.lisp")
#P"/Users/jordan/src/lisp/cl-bitcoin/bitcoin.lisp"
CL-USER> (load "/Users/jordan/src/lisp/cl-bitcoin/classes.lisp")
#P"/Users/jordan/src/lisp/cl-bitcoin/classes.lisp"
CL-USER> (load "/Users/jordan/src/lisp/cl-bitcoin/functions.lisp")
#P"/Users/jordan/src/lisp/cl-bitcoin/functions.lisp"
CL-USER> (btc:help "getinfo")
#<BTC::BTC-SINGLE #x3020017DBDDD>
CL-USER> 

以及生成函数的代码:

;;;; package information

(in-package #:btc)

;;; externally visible functions - this class contains the public api for
;;; cl-bitcoin as well as the function building framework that we need to
;;; easily handle the multiple return types that are possible from the
;;; bitcoind server methods

;; function building framework - resolving function return types into 
;; specific btc objects (as defined in classes.lisp)

(defun create-btc-obj (fn result err id)
  (case fn
    ((:getbalance :help) (make-btc-single result err id))
    (otherwise (error "Unable to parse function ~S to a btc object" fn))))

(defmacro defbtcfun (name &rest args)
  (let ((g (gensym)) (result (gensym)) (err (gensym)) (id (gensym)))
    `(progn
       (defun ,name ,args
     (let ((,g (intern (string ',name) :keyword)))
       (multiple-value-bind (,result ,err ,id) (get-bitcoind-result ,g ,@args)
         (create-btc-obj ,g ,result ,err ,id))))
       (export ',name 'btc))))

;; function definitions (each of these functions should have a corresponding case in 
;; create-btc-obj above, otherwise a condition will be signaled

(defbtcfun help method)

(defbtcfun getbalance account minconf)

【问题讨论】:

  • “问题是与我的包相关的所有内容都不可用。这包括直接从我的 package.lisp 文件导出的函数。”请举个例子?什么不可用?你的意思是一些函数定义没有被评估?或者没有导出符号?您遇到了什么意外行为?
  • 在我的 defpackage 中,我明确导出了 5 个函数 - 加载后我的 btc 包中没有这些函数。此外,在quickload 之后,我的宏将导出的所有符号(这些符号都已导出并且在我单独加载文件时在 btc 包中可用)不可用
  • 在我看来,考虑到导出在包声明中是明确的,因此没有对函数定义进行评估,但我不确定。
  • 您能否向我们展示您遇到的错误?
  • 很高兴听到您解决了这个问题。您可以将其发布为答案并将其标记为已接受。这将帮助可能遇到相同情况的其他人(因为搜索问题和答案比搜索 cmets 更容易),并且有助于减少没有接受答案的问题数量。很高兴听到你解决了; Lisping 快乐!

标签: lisp common-lisp quicklisp


【解决方案1】:

Jordan Kaye 将此作为a comment 发布,但从未将其变成答案:

原来这只是一个不正确的配置问题 asdf by me.. 我不小心将项目设置为不正确的 目录。加载项目时,快速加载实际上是在加载一个 .asd 文件与我预期的完全不同。所以, 当我手动加载(正确的)文件时,代码的工作原理是 预期 - 快速加载加载了错误的文件。非常感谢 你的帮助,它让我找出了原因!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-27
    • 1970-01-01
    • 2023-03-26
    • 2018-05-10
    • 2019-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多