Haskell的main
函数正是我想要的:评估文件何时自己加载(例如./myfile.hs
或runhaskell myfile.hs
),而不是其他情况。当文件由另一个文件导入时,将不会调用main
。 newLISP也具有此功能。
Common Lisp是否有相同的代码?
我为CLISP阅读了source code。以下是用户输入clisp myfile.lisp
或./myfile.lisp
时发生的情况:
myfile.lisp
保存为p->argv_execute_file
。(LOAD "p->argv_execute_file")
并将其推送到Lisp堆栈。*args*
。 CLISP从不使用引用p->argv_execute_file
的Lisp变量,因此无法识别myfile.lisp
是由用户直接加载,还是由另一个Lisp文件加载。如果(car *args*)
只有myfile.lisp
,我的任务就很简单。
注意:如果文件是从REPL加载的话,Shebang会给CLISP带来麻烦,所以我把这段代码放在~/.clisprc.lisp
中:
(set-dispatch-macro-character #\# #\!
(lambda (stream character n)
(declare (ignore character n))
(read-line stream nil nil t)
nil))
答案 0 :(得分:2)
我找到了solution。这有点狡猾,但它确实有效。我很快就会将其修改为CLISP以外的CL实现。
#!/bin/sh
#|
exec clisp -q -q $0 $0 ${1+"$@"}
exit
|#
;;; Usage: ./scriptedmain.lisp
(defun main (args)
(format t "Hello World!~%")
(quit))
;;; With help from Francois-Rene Rideau
;;; http://tinyurl.com/cli-args
(let ((args
#+clisp ext:*args*
#+sbcl sb-ext:*posix-argv*
#+clozure (ccl::command-line-arguments)
#+gcl si:*command-args*
#+ecl (loop for i from 0 below (si:argc) collect (si:argv i))
#+cmu extensions:*command-line-strings*
#+allegro (sys:command-line-arguments)
#+lispworks sys:*line-arguments-list*
))
(if (member (pathname-name *load-truename*)
args
:test #'(lambda (x y) (search x y :test #'equalp)))
(main args)))
答案 1 :(得分:0)
<德尔> (eval-when (situation*) ...)
德尔>
更新抱歉这个令人困惑的答案。
我可能错了,但似乎不可能完全按照你的意愿行事。我会创建一个shell脚本并调用clisp -i myfile.lisp -x (main)
。
有没有理由不让它可执行(描述here)?
P.S。 Common Lisp是一种语言,clisp
是其中一种实现。