Запутался в ``ql:quickload`` и исполняемых скриптах в SBCL
Я пытался использовать пакеты Quicklisp в моем исполняемом скрипте. (Тривиальный) рабочий пример:
#!/usr/bin/sbcl --script
(eval-when (:compile-toplevel :load-toplevel :execute)
(ql:quickload "lisp-unit")) ;as explained by another question
(defpackage :test
(:use :cl :lisp-unit))
(format t "This is a test.")
После chmod
ING файл с этим кодом (называется test.lisp
), Я пытался выполнить это. Однако затем я получил следующее сообщение об ошибке:
Unhandled SB-C::INPUT-ERROR-IN-LOAD in thread #<SB-THREAD:THREAD
"main thread" RUNNING
{1002C16923}>:
READ error during LOAD:
Package QL does not exist.
Line: 4, Column: 15, File-Position: 95
Stream: #<SB-SYS:FD-STREAM
for "file /home/koz/Documents/Programming/CL/trees/test.lisp"
{1002C19A93}>
Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {1002C16923}>
0: ((LAMBDA NIL :IN SB-DEBUG::FUNCALL-WITH-DEBUG-IO-SYNTAX))
1: (SB-IMPL::CALL-WITH-SANE-IO-SYNTAX #<CLOSURE (LAMBDA NIL :IN SB-DEBUG::FUNCALL-WITH-DEBUG-IO-SYNTAX) {1002C2498B}>)
2: (SB-IMPL::%WITH-STANDARD-IO-SYNTAX #<CLOSURE (LAMBDA NIL :IN SB-DEBUG::FUNCALL-WITH-DEBUG-IO-SYNTAX) {1002C2495B}>)
3: (PRINT-BACKTRACE :STREAM #<SB-SYS:FD-STREAM for "standard error" {1002C14CF3}> :START 0 :FROM :INTERRUPTED-FRAME :COUNT NIL :PRINT-THREAD T :PRINT-FRAME-SOURCE NIL :METHOD-FRAME-STYLE NIL)
4: (SB-DEBUG::DEBUGGER-DISABLED-HOOK #<SB-C::INPUT-ERROR-IN-LOAD {1002C1CB93}> #<unavailable argument>)
5: (SB-DEBUG::RUN-HOOK *INVOKE-DEBUGGER-HOOK* #<SB-C::INPUT-ERROR-IN-LOAD {1002C1CB93}>)
6: (INVOKE-DEBUGGER #<SB-C::INPUT-ERROR-IN-LOAD {1002C1CB93}>)
7: (ERROR #<SB-C::INPUT-ERROR-IN-LOAD {1002C1CB93}>)
8: (SB-C:COMPILER-ERROR SB-C::INPUT-ERROR-IN-LOAD :CONDITION #<SB-INT:SIMPLE-READER-PACKAGE-ERROR "Package ~A does not exist." {1002C1CAA3}> :STREAM #<SB-SYS:FD-STREAM for "file /home/koz/Documents/Programming/CL/trees/test.lisp" {1002C19A93}>)
9: (SB-C::READ-FOR-COMPILE-FILE #<SB-SYS:FD-STREAM for "file /home/koz/Documents/Programming/CL/trees/test.lisp" {1002C19A93}> 25 SB-C::INPUT-ERROR-IN-LOAD)
10: (SB-INT:LOAD-AS-SOURCE #<SB-SYS:FD-STREAM for "file /home/koz/Documents/Programming/CL/trees/test.lisp" {1002C19A93}> :VERBOSE NIL :PRINT NIL :CONTEXT "loading")
11: ((FLET SB-FASL::LOAD-STREAM :IN LOAD) #<SB-SYS:FD-STREAM for "file /home/koz/Documents/Programming/CL/trees/test.lisp" {1002C19A93}> NIL)
12: (LOAD #<SB-SYS:FD-STREAM for "file /home/koz/Documents/Programming/CL/trees/test.lisp" {1002C19A93}> :VERBOSE NIL :PRINT NIL :IF-DOES-NOT-EXIST T :EXTERNAL-FORMAT :DEFAULT)
13: ((FLET SB-IMPL::LOAD-SCRIPT :IN SB-IMPL::PROCESS-SCRIPT) #<SB-SYS:FD-STREAM for "file /home/koz/Documents/Programming/CL/trees/test.lisp" {1002C19A93}>)
14: ((FLET #:WITHOUT-INTERRUPTS-BODY-140 :IN SB-IMPL::PROCESS-SCRIPT))
15: (SB-IMPL::PROCESS-SCRIPT "./test.lisp")
16: (SB-IMPL::TOPLEVEL-INIT)
17: ((FLET #:WITHOUT-INTERRUPTS-BODY-89 :IN SAVE-LISP-AND-DIE))
18: ((LABELS SB-IMPL::RESTART-LISP :IN SAVE-LISP-AND-DIE))
unhandled condition in --disable-debugger mode, quitting
Я не уверен, что здесь происходит - если я пытаюсь сделать что-то похожее с верхнего уровня (т.е. запустить SBCL, загрузить lisp-unit
с помощью ql:quickload
и т. д.), я ничего подобного не получаю.
2 ответа
В SBCL, --script
не загружает ваши файлы инициализации. Если вы хотите использовать Quicklisp, вы должны договориться о его загрузке. Это обычно означает что-то вроде (load "~/quicklisp/setup.lisp")
перед использованием чего-либо, связанного с Quicklisp.
Я не думаю, что SBCL и Quicklisp отлично подходят для задач сценариев. Когда я пишу сценарии, я обычно не ожидаю, что они будут получать что-то из Интернета, например ql:quickload
делает. Quicklisp также довольно многословен. Загрузка SBCL FASL довольно медленная. Взятые вместе, это не очень хороший сценарий.
Я очень сильно предпочитаю загружать все, что мне нужно использовать, в сеанс Common Lisp, а затем вызывать функции, чтобы выполнить работу. Когда я не могу использовать это (например, для запуска чего-либо из cron или из Makefile), я часто использую buildapp для создания исполняемых файлов.
Вы должны рассмотреть возможность использования cl-launch, который сделан для этой цели. Вы можете включить Quicklisp, передав опцию -Q. Ваш пример кода будет выглядеть примерно так:
#!/usr/bin/cl -Q -p lisp-unit
(eval-when (:compile-toplevel :load-toplevel :execute)
(ql:quickload "lisp-unit")) ;as explained by another question
(defpackage :test (:use :cl :lisp-unit))
(defun main (argv) "Code goes here")