2014-09-15 4 views
8

Я пытался использовать пакеты Quicklisp в исполняемом скрипте. A (тривиальный) рабочий пример:Смутно о `` ql: quickload` и исполняемых скриптах в SBCL

#!/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 ИНГ файла с этим кодом в нем (так называемом 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, и т.д.), Я не получаю ничего подобного.

+0

Я бы удостоверился, что в скрипте действительно загружен quicklisp. Сделайте это в отдельном EVAL-WHEN перед его использованием ... –

ответ

10

В SBCL --script не загружает ваши файлы инициализации. Если вы хотите использовать Quicklisp, вам нужно будет его загрузить. Обычно это означает что-то вроде (load "~/quicklisp/setup.lisp"), прежде чем использовать что-либо, связанное с Quicklisp.

Я не думаю, что SBCL и Quicklisp отлично подходят для задач сценариев. Когда я пишу скрипты, я обычно не ожидаю, что они заберут материал из Интернета, как это делает ql:quickload. Quicklisp также довольно многословный. Загрузка FASL SBCL довольно медленная. Взятые все вместе, это не делает для очень хорошего опыта сценариев.

Я очень сильно загружаю все, что мне нужно, чтобы использовать в общем сеансе Lisp, а затем вызывать функции, чтобы все было сделано. Когда я не могу использовать это (например, для запуска файлов из cron или из Makefile), я часто использую buildapp для создания исполняемых файлов.

+0

Можете ли вы использовать buildapp вместе с Quicklisp? У меня есть куча вещей из Quicklisp, которые я хочу использовать (в основном такие вещи, как Alexandria), но я не уверен, как это взаимодействует с buildapp. –

+2

Да. Есть несколько шагов, но это возможно. Я использую 'ql: write-asdf-manifest-file' в quicklisp вместе с' -manifest-file' в buildapp, чтобы убедиться, что они находятся на одной странице. В Makefiles я обычно делаю это, создавая проект в предварительном порядке, чтобы убедиться, что все необходимые условия установлены, а затем снова создайте его через buildapp после записи файла манифеста. – Xach

1

Вы должны рассмотреть возможность использования 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") 
+0

Я попытался создать его, клонировав репо и вызвав '' make'', но он не сработал, не получив впечатляющего сообщения об ошибке. –