2012-01-03 30 views
3

我写了两个函数在两个分开的文件,假设是文件A.lisp和B.lisp,其中两个文件都有一些主程序测试代码和A.lisp将调用B.lisp中的函数。这意味着直接在A.lisp中使用load方法将执行B.lisp中的主代码,这不应该发生。在我看来,这些文件太小而不能用包装之类的东西来考虑。有没有像Python的`if __name__ == _ _main __“:`东西在Common Lisp

在Common Lisp中有没有像Python的if __name__ == "__main__":的东西?封装在此条件下的顶级代码仅在当前文件是主要模块(即正在运行的程序)时才会执行,但是如果它作为库导入则不会执行。

+0

我问了[有关Clojure的类似问题](http://stackoverflow.com/questions/973106/what-is-the-clojure-equivalent-of-the-python-idiom-if-name-main),而不是Common Lisp,但是您可能会发现一些有用的回复,特别是当前评分最高的回复。 – 2013-06-20 21:12:05

+0

谢谢蒂姆!这真的很有帮助。 – lastland 2013-07-01 08:22:01

回答

6

包只是符号的命名空间。他们没有说关于加载或编译代码的任何信息。

Common Lisp在ANSI Common Lisp标准中没有库,模块甚至像'main'模块/例程的概念。该标准定义了两个例程PROVIDEREQUIRE。但那些没有很好的说明。

大多数应用程序和库使用“系统”工具来构造,指定,编译和加载代码。

有一个叫做ASDF的'免费'。 '另一个系统定义设施'。对于大多数类型的应用程序,像ASDF这样的工具很有用。对于原始应用程序,您可以使用标准功能编写自己的工具,如COMPILE-FILELOAD

Nick Levine为ASDF写了一篇教程(他放弃Lisp书籍的一部分):Systems

一些Lisp实现具有更广泛的创建应用程序的设施(例如使用Clozure Common Lisp编写的Mac OS X应用程序)。

2

评估顶级表格。

你可以定义一个主要功能在下面的例子中,你可以调用任何你喜欢的功能:

a.lisp

(defun main() 
    ...)

b.lisp

(load "a.lisp") 
(main)
+0

但是,如果我想单独运行A.lisp来进行某些测试工作,该怎么办? – lastland 2012-01-03 14:36:38

+0

你在a.lisp和b.lisp中肯定有一些入口点。 – sbenitezb 2012-01-03 14:47:30

+0

但是我必须能够执行A.lisp中的主函数,如果我想单独执行。如果main函数调用仅存在于B.lisp中,我该怎么做? – lastland 2012-01-03 15:10:51

1

我真的不知道它是如何在Python中工作,但它看起来像一个文件是 一个模块,两个文件是两个不同的模块。这不是 Common Lisp的情况。如果你没有定义任何包,当你load一个文件, 所有的定义将在当前包中可用(CL-USER是 默认)。这更像是你将代码粘贴到REPL中。

但是包并不是很难使用。

在A.lisp:

(defpackage foo 
    (:use #:cl) 
    (:export main)) 

(in-package :foo) 

(defun main() 
    (do-some-stuff) 
    (baz:main some-args)) 

在B.lisp:

(defpackage baz 
    (:use #:cl) 
    (:export main)) 

(in-package :baz) 

(defun main (some-args) 
    (do-some-stuff)) 

您可以阅读 The Complete Idiot's Guide to Common Lisp PackagesPCL chapter on packages

4

if __name__ == "__main__":成语对Python非常具体,甚至Python社区中的一些人也考虑将其用于测试代码不良风格。

由于Common Lisp高度重视REPL中的交互式开发,每次要运行测试时都必须重新加载整个文件实际上是一个缺点。只需将测试放入函数定义而不是顶层,它就可以工作并且更方便。

+0

所以没有办法编写代码,只有当我用'clisp myfile.lisp'运行文件而不是'(load'myfile)'时才执行? – zstewart 2015-10-28 18:56:04

+0

您可以将在运行文件时仅作为脚本进行评估的代码放入您在评估脚本时从命令行调用的特殊函数中。我只安装了SBCL而不是CLISP,所以我无法测试你需要用CLISP来做这件事,用SBCL你可以做'sbcl --noinform --load myfile.lisp --eval'(main)' --quit'这当然比sbcl --script myfile.lisp长得多,当代码处于顶层时,您可以执行此操作。所以更简单的方法是将脚本加入一个额外的文件来加载库部分。 – 2015-10-28 21:21:21