Почему не asdf: load-system создает пакет

Я пытаюсь использовать функциональность asdf для запуска моего набора тестов из repl, но при использовании quicklisps quickload, если не удается с первой попытки загрузить foo и успешно на второй.

(in-package :cl-user)
(defpackage :foo-system
  (:use :cl :asdf))
(in-package :foo-system)

(asdf:defsystem :foo
  :components ((:file "foo")))

(asdf:defsystem :foo-tests
  :depends-on (:foo)
  :components ((:file "foo-tests")))

(defmethod asdf:perform ((op test-op) (system (eql (find-system :foo))))
  (asdf:load-system 'foo-tests)
  (foo-tests:run-tests))

Это имеет смысл, потому что, когда я компилирую файл asd, ошибка появляется во второй форме метода asdf: perfom def. Ошибка при замене nclack на foo:

../../nclack/nclack.asd:36:27: ошибка чтения: ошибка чтения во время КОМПИЛЯЦИИ-ФАЙЛА:

  Package NCLACK-TESTS does not exist.

    Line: 36, Column: 27, File-Position: 1034

    Stream: #<SB-SYS:FD-STREAM
              for "file /Users/PuercoPop/quicklisp/local-projects/nclack/nclack.asd"
              {1005DB11A3}>

что соответствует строке (foo-tests: run-tests). Получается, что «загрузка» системы отличается от компиляции ее форм? Или почему пакет не определяется после загрузки системы? Любые идеи? Я в растерянности.


person PuercoPop    schedule 22.08.2013    source источник
comment
find-system - это функция в пространстве имен asdf. То же самое и с test-op. В противном случае это не должно компилироваться / если только эти символы не были объявлены в пакете, который был актуальным на момент компиляции.   -  person    schedule 22.08.2013
comment
Спасибо, что поймали еще одну мою ошибку. Теперь он компилируется, если я удалю форму (foo: tests-run-tests), но это ошибка другого типа. Я собираюсь обновить код вопроса, чтобы исправить указанную вами ошибку.   -  person PuercoPop    schedule 22.08.2013


Ответы (2)


Когда вы compile-file это:

(defmethod asdf:perform ((op test-op) (system (eql (find-system :foo))))
  (asdf:load-system 'foo-tests)
  (foo-tests:run-tests))

первый шаг - это read всю форму. Reading включает интернирование всех найденных символов. Однако во время чтения форма не была выполнена, поэтому система foo-tests еще не загружена. Поскольку эта система включает пакет foo-tests, который еще не загружен, вы не можете вставить какие-либо символы в этот пакет во время чтения этой формы.

Вот почему compile-file выдает ошибку, отображаемую при попытке read формы.

Мне кажется, что нужно (funcall (find-symbol "RUN-TESTS" #:foo-tests)).

person Svante    schedule 22.08.2013
comment
Это могло быть, но имя пакета было другим? - person Rainer Joswig; 22.08.2013
comment
Я думаю, что вопрос не всегда заменял его настоящее системное имя на foo в вопросе. - person Svante; 22.08.2013
comment
Мне приходилось делать аналогичные обходные пути по целому ряду причин в прошлом, это, кажется, один из случаев, когда (funcall (find-symbol ...)) неизбежно (в случае, когда я помню, что мне приходилось делать это в прошлом, я быстро создавал оболочка вокруг CLX, позволяющая сохранять и восстанавливать состояние окна приложения при перезапусках). - person Vatine; 22.08.2013
comment
Хотя (funcall (find-symbol run-tests)) не работает, ваш ответ проясняет, почему он не работает. Я не знал, что читаю интернированные символы. Спасибо, что пролили свет там, где была тьма. - person PuercoPop; 22.08.2013
comment
Осторожно с корпусом ридера. RUN-TESTS называет другой символ, чем run-tests. Регистр считывателя по умолчанию упорядочивает имена символов. - person Svante; 22.08.2013
comment
PuercoPop просто попытался изменить этот ответ следующим образом (я его не проверял): Похоже, что asdf теперь включает функцию asdf / package: symbol-call для этого варианта использования, как это видно на iolib. - person Svante; 31.01.2014

Первый:

Если вы определяете новый пакет FOO-SYSTEM и используете пакет ASDF, а затем используете символы asdf по-прежнему с префиксом, то вы как бы побеждаете использование пакета. Зачем его вообще использовать, если вы ставите префиксы к символам?

Трудно сказать, в чем заключается ошибка, поскольку мы не видим трассировки и не видим файлы.

В любом случае вам нужно убедиться, что пакет доступен во время компиляции файла. Например, компиляция формы DEFPACKAGE может не изменить среду времени компиляции. Вам необходимо заполнить форму DEFPACKAGE. Вам также необходимо убедиться, что определение пакета загружается во время операции load system.

Если пакет не существует, необходимо убедиться, что он существует.

person Rainer Joswig    schedule 22.08.2013
comment
Определение системы foo было отредактированным, поэтому префикс asdf был ее остатком, спасибо, что заметили это. Вы можете увидеть обратную трассировку [здесь] [paste.lisp.org/+2YXG] Я зная, что мне нужно выполнить форму defpackage, вопрос в том, как использовать asdf для этого. Извините, мой вопрос был непонятным. - person PuercoPop; 22.08.2013