2016-07-27 117 views
3

在C语言中,以确保我们不会再包括包含我们用以下结构标题:的#ifndef Common Lisp中

#ifndef UTILS 
#define UTILS 

#include "my_utils.h" 

#endif 

我已经打破了我的Lisp程序到单独的文件;多个文件有时使用相同的文件(例如,my_utilities被多个文件使用)。当我运行该程序时,我收到警告说我正在重新定义事件(多次调用同一文件的load)。

这可以通过在C中执行与#ifndef类似的操作来解决。什么是Common Lisp等效或标准方法?

我是Lisp的新手。让我知道是否有最佳实践(也许,我的程序的不同构造方法?),我错过了。

+2

您应该使用[asdf](https://stackoverflow.com/documentation/common-lisp/670/asdf-another-system-definition-facility#t=20160727160132848467)来定义系统。 – jkiiski

+0

这就是我正在寻找的。谢谢。 – audrow

回答

7

你问

的预处理条件类似于C #if直接模拟的问题是, #+读出时间条件化设施。

你想的问题要问

为了避免文件的多个负载,您可以使用标准的 (但不建议使用) provide/require设施, 或附加系统,如ASDF

+0

这就是我想问的。谢谢。 – audrow

+1

不用客气 – sds

6
  1. 对于Common Lisp的应用程序和库,最好使用系统管理工具。像ASDF或任何你的实现可能提供。系统是具有依赖性和各种操作(加载,编译,...)的文件的集合。

  2. 您可以随时检查运行时的状态并执行一些操作。

实施例:

(unless (fboundp 'foobar) 
    (require "foo") 
    (load "bar")) 

(unless (find-package 'foobar) 
    (require "foo") 
    (load "bar")) 
  • PROVIDEREQUIRE是内置函数对于这一点。如果您需要模块它将被加载,除非已经有provided。不幸的是,这个功能在标准中没有详细说明,但是实现可能会提供有用的功能。

  • Common Lisp运行时列表功能的名单*features*。您可以使用它来宣传和检查功能。

  • 例子:

    在音乐库:

    (push :cool-new-graphics-library cl:*features*) 
    

    在应用程序代码:

    (when (member :cool-new-graphics-library cl:*features*) 
        (funcall (find-symbol "DRAW-SPACE-SHIP" "CNGL") 
          :death-star)) 
    

    的Common Lisp提供了一种条件化是一个读取时间。当:cool-new-graphics-library功能存在,因此才将稍后执行下面的代码才会被读:

    #+cool-new-graphics-library(cngl:draw-space-ship :death-star) 
    

    Common Lisp中,您还可以表达一些逻辑:

    #+(and lispworks cool-new-graphics-library) 
        (cngl:draw-space-ship :enterprise) 
    
    #-cool-new-graphics-library(warn "no cool graphics library available") 
    

    注意您可以强制Lisp语言在编译时执行代码:

    (eval-when (:load-toplevel :compile-toplevel :execute) 
        #+(and lispworks cool-new-graphics-library) 
        (cngl:draw-space-ship :enterprise) 
    
        #-cool-new-graphics-library(warn "no cool graphics library available") 
    ) 
    

    对于这项工作的EVAL-WHEN必须是在一个文件中的顶层。这意味着它不会在嵌套表单中工作得很深。它一个顶级PROGNLOCALLYMACROLETSYMBOL-MACROLET里面工作,虽然。

    因此EVAL-WHEN允许您运行代码是当前编译文件的一部分。这个代码比可以查找加载的系统,提供的模块,可用的函数等等。

    +0

    非常彻底。谢谢。 – audrow