Как: использовать системы, которые я создаю с помощью ASDF?

System-A и System-B - это системы, созданные с использованием ASDF. Они оба имеют системные определения в .asd файлы и определения пакетов, :system-a а также :system-bсоответственно.

Я хочу, чтобы Система-А :use Пакет System-B в его определении пакета. Я хочу, чтобы я мог использовать символы System-B в System-A, не обращаясь к пакету System-B. В частности, я хочу использовать symbol скорее, чем system-b:symbol,

В настоящее время в определении пакета System-A я пытаюсь :use :system-b, Это работает для интернирования библиотек, которые я импортировал с использованием QuickLisp, но не для моих собственных систем.

Как я могу :use :system-b чтобы я интернировал символы в пакете System-A?

1 ответ

Решение

Здесь я покажу решения, которые я нашел:


Первый - экспортировать символы в определении пакета. Используя мой пример, в определении пакета System-B

(defpackage :system-b
  (:use :cl)
  (:export :symbol1
           :symbol2
           ...))

И в определении пакета System-A

(defpackage :system-a
  (:use :cl
        :system-b))

Затем, когда вы (in-package :system-a) у вас есть доступ к экспортированным символам System-B.


Во-вторых, если у вас есть много символов для экспорта (создание пакета утилит), вы можете использовать следующее, найденное здесь.

(let ((package (find-package :foo)))
  (do-all-symbols (symbol package)
    (when (eql (symbol-package symbol) package)
      (export symbol))))

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


Третий вариант экспорта символов - это cl-annot, который, помимо прочего, позволяет вам добавлять к функции префикс @export экспортировать это. Например,

@export
(defun foobar ()
   ...)

эквивалентно

(progn
  (export 'foobar)
  (defun foobar ()
    ...))
Другие вопросы по тегам