从命令行启动 Lisp 程序时如何指定包名称?
How can I specify the package name when launching a Lisp program from the command line?
我正在从 shell 脚本中调用 Lisp 函数(以及其他一些东西)。为简洁起见,下面是脚本的相关部分:
./gcl -load /tmp/calendrica-3.0.cl -batch -eval '(format T "~a"
(CC3::sunset (CC3::fixed-from-gregorian (CC3::gregorian-date 1996
CC3::february 25)) CC3::jerusalem))'
728714.7349874675
上面的代码工作正常,但我必须为每个使用的符号附加包名 CC3;这使得代码笨重且难以输入。
我试着像这样简化它,使用 use-package
:
./gcl -load /tmp/calendrica-3.0.cl -batch -eval '(format T "~a"
(use-package "CC3") (sunset (fixed-from-gregorian (gregorian-date 1996 february 25)) jerusalem))'
更容易阅读和输入,但不幸的是它不起作用。我已经尝试了各种方法来包含 use-package
指令,但到目前为止没有成功。
甚至可以在通过 GNU Common Lisp (gcl) 加载指令启动 Lisp 程序时包含 use-package
指令吗?
更新:
解决方案是按照已接受答案的建议使用多个评估。
./gcl -load /tmp/calendrica-3.0.cl -batch -eval
'(use-package "CC3")' -eval '(format T "~a" (sunset
(fixed-from-gregorian (gregorian-date 1996 february 25)) jerusalem))'
也许可以这样做,但会很难看。
如果你给它一个表单表单评估,它会先读取表单。因此,在评估期间更改 reader(告诉新包,...)为时已晚。因此需要提前完成。
CL-USER 1 > (eval (read-from-string "(foo::bar)"))
Error: Reader cannot find package FOO.
Better:
CL-USER 5 > (eval '(progn (defpackage foo (:use "CL"))
(read-from-string "(foo::bar)")))
(FOO::BAR)
因此,如果您想将单个表单传递给 eval,您可以编写 which 首先创建包,然后 reads/evals 从字符串中创建,该字符串在表单中进行编码。棘手。
备选方案:
也许 Lisp 在启动时允许多个 -eval
形式?做任何你需要初始化 Lisp 的事情,以了解第一个 -eval
形式的包。然后让代码以第二种形式执行。
写一个文件,把必要的表格放在那里。加载它。由于一个文件可以包含多个表单,因此您可以在顶部添加 DEFPACKAGE
、IN-PACKAGE
或类似内容,然后根据它在文件中添加其余代码。
也许你可以使用多个 eval,这是我对 sbcl 所做的。
#!/bin/sh
sbcl --noinform \
--eval '(load "boot.lisp")' \
--eval '(in-package #:my-pkg)' \
--eval "(do-something-useful)" # do-something-useful is in my-pkg
我正在从 shell 脚本中调用 Lisp 函数(以及其他一些东西)。为简洁起见,下面是脚本的相关部分:
./gcl -load /tmp/calendrica-3.0.cl -batch -eval '(format T "~a" (CC3::sunset (CC3::fixed-from-gregorian (CC3::gregorian-date 1996 CC3::february 25)) CC3::jerusalem))' 728714.7349874675
上面的代码工作正常,但我必须为每个使用的符号附加包名 CC3;这使得代码笨重且难以输入。
我试着像这样简化它,使用 use-package
:
./gcl -load /tmp/calendrica-3.0.cl -batch -eval '(format T "~a" (use-package "CC3") (sunset (fixed-from-gregorian (gregorian-date 1996 february 25)) jerusalem))'
更容易阅读和输入,但不幸的是它不起作用。我已经尝试了各种方法来包含 use-package
指令,但到目前为止没有成功。
甚至可以在通过 GNU Common Lisp (gcl) 加载指令启动 Lisp 程序时包含 use-package
指令吗?
更新: 解决方案是按照已接受答案的建议使用多个评估。
./gcl -load /tmp/calendrica-3.0.cl -batch -eval '(use-package "CC3")' -eval '(format T "~a" (sunset (fixed-from-gregorian (gregorian-date 1996 february 25)) jerusalem))'
也许可以这样做,但会很难看。
如果你给它一个表单表单评估,它会先读取表单。因此,在评估期间更改 reader(告诉新包,...)为时已晚。因此需要提前完成。
CL-USER 1 > (eval (read-from-string "(foo::bar)"))
Error: Reader cannot find package FOO.
Better:
CL-USER 5 > (eval '(progn (defpackage foo (:use "CL"))
(read-from-string "(foo::bar)")))
(FOO::BAR)
因此,如果您想将单个表单传递给 eval,您可以编写 which 首先创建包,然后 reads/evals 从字符串中创建,该字符串在表单中进行编码。棘手。
备选方案:
也许 Lisp 在启动时允许多个
-eval
形式?做任何你需要初始化 Lisp 的事情,以了解第一个-eval
形式的包。然后让代码以第二种形式执行。写一个文件,把必要的表格放在那里。加载它。由于一个文件可以包含多个表单,因此您可以在顶部添加
DEFPACKAGE
、IN-PACKAGE
或类似内容,然后根据它在文件中添加其余代码。
也许你可以使用多个 eval,这是我对 sbcl 所做的。
#!/bin/sh
sbcl --noinform \
--eval '(load "boot.lisp")' \
--eval '(in-package #:my-pkg)' \
--eval "(do-something-useful)" # do-something-useful is in my-pkg