Понимание загрузки пакетов

(решено, смотрите комментарии)

Недавно я работал над 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)

person Jordan Kaye    schedule 29.11.2013    source источник
comment
Проблема в том, что все, что связано с моим пакетом, недоступно. Сюда входят функции, которые экспортируются непосредственно из моего файла package.lisp. Пожалуйста, приведите пример? Что недоступно? Вы имеете в виду, что какое-то определение функции не было оценено? Или что символ не экспортируется? С каким неожиданным поведением вы столкнулись?   -  person Joshua Taylor    schedule 30.11.2013
comment
В моем defpackage я явно экспортирую 5 функций - ни одна из этих функций не доступна в моем btc пакете после загрузки. Кроме того, все символы, которые будут экспортированы моими макросами (все они экспортируются и доступны в пакете btc, когда я загружаю файлы по отдельности), недоступны после quickload   -  person Jordan Kaye    schedule 30.11.2013
comment
Мне кажется, что определение функции не оценивается, учитывая, что экспорт явно указан в объявлении пакета, но я не уверен в этом.   -  person Jordan Kaye    schedule 30.11.2013
comment
Не могли бы вы показать ошибку, которую вы получаете?   -  person Joshua Taylor    schedule 30.11.2013
comment
Я отредактировал сообщение, чтобы включить REPL.   -  person Jordan Kaye    schedule 30.11.2013
comment
Это образ; ничего из этого не будет отображаться в поисковой системе. Пожалуйста, скопируйте и вставьте текст. Во всяком случае, он говорит, что в пакете btc нет внешнего символа с именем help. Глядя на определение пакета btc, я вижу только пять экспортированных символов, и help не входит в их число. После загрузки файлов help экспортируется из btc. Как определяется help и где находится код, экспортирующий его из пакета?   -  person Joshua Taylor    schedule 30.11.2013
comment
Спасибо за размещение текста!   -  person Joshua Taylor    schedule 30.11.2013
comment
Нет проблем — я также включил другой запрошенный вами код. Но в пакете после быстрой загрузки нет доступных функций, в том числе и явно указанных.   -  person Jordan Kaye    schedule 30.11.2013
comment
что произойдет, если вы (ql:quickload :btc) во второй раз, а не загружаете файлы вручную? Дает ли quickload два раза нужный экспорт символов?   -  person Joshua Taylor    schedule 30.11.2013
comment
Вы уверены, что файлы, которые загружает quicklisp, совпадают с теми, которые вы загружаете вручную? Я знаю, что каталог quicklisp по умолчанию для локальных проектов - ~/quicklisp/local-projects/...   -  person Joshua Taylor    schedule 30.11.2013
comment
Я взял ваш код и вставил, когда я запускаю SBCL из командной строки и (ql:quickload 'btc), вывод, который я вижу, включает: * (ql:quickload 'btc) \ To load "btc": \ Load 1 ASDF system: \ btc \ ; Loading "btc" \ ........ \ (BTC) \ * 'btc:help \ BTC:HELP. Этот ряд точек печатается во время загрузки файла. Я не вижу этого в вашем выводе, и мне интересно, действительно ли quicklisp вызывает загрузку ваших файлов. Он явно загружает определение пакета, поскольку пакет доступен, но, возможно, по какой-то причине он не загружает код.   -  person Joshua Taylor    schedule 30.11.2013
comment
Оказывается, это была просто проблема с неправильной конфигурацией asdf с моей стороны. Я случайно настроил проект в неправильном каталоге. При загрузке проекта quickload фактически загружал совершенно другой файл .asd, чем тот, который я ожидал. Итак, когда я загрузил (правильные) файлы вручную, код работал, как и ожидалось — quickload загружал неправильные файлы. Большое спасибо за помощь, это помогло мне выяснить причину!   -  person Jordan Kaye    schedule 30.11.2013
comment
Рад слышать, что у вас все решилось. Вы можете опубликовать это как ответ и пометить как принятое. Это помогло бы другим, кто может столкнуться с такой же ситуацией (поскольку поиск по вопросам и ответам проще, чем поиск по комментариям), и поможет снизить количество вопросов без принятых ответов. Рад слышать, что у вас все получилось; счастливый Лиспинг!   -  person Joshua Taylor    schedule 30.11.2013
comment
Я второй @JoshuaTaylor - пожалуйста, опубликуйте ответ на этот вопрос и примите его.   -  person verdammelt    schedule 12.01.2014


Ответы (1)


Джордан Кэй опубликовал это как комментарий, но так и не превратил его в ответ:

Оказывается, это была просто проблема с неправильной конфигурацией asdf с моей стороны. Я случайно настроил проект в неправильном каталоге. При загрузке проекта quickload фактически загружал совершенно другой файл .asd, чем тот, который я ожидал. Итак, когда я загрузил (правильные) файлы вручную, код работал, как и ожидалось — quickload загружал неправильные файлы. Большое спасибо за помощь, это помогло мне выяснить причину!

person Community    schedule 17.06.2014