配置文件在什么时候成为编程语言?

时间:2009-03-15 18:07:14

标签: configuration programming-languages configuration-files config

我一直在考虑配置文件及其与代码的关系一段时间了,根据风的日期和方向,我的意见似乎有所改变。虽然我不断回过头来学习Lisp时的第一次实现:数据和代码之间几乎没有什么区别。对配置文件来说,这似乎是双重的。从正确的角度来看,Perl脚本只不过是perl的配置文件。这往往会对质量保证和分工等任务产生相当严重的后果,例如谁应该负责更改配置文件。

从配置文件到完全成熟的语言的蠕变通常很慢,似乎是由拥有通用系统的愿望驱动的。大多数项目似乎从一些配置项开始,比如在哪里写日志,在哪里查找数据,用户名和密码等等。但随后它们开始增长:功能开始能够打开或关闭,操作的时间和顺序开始被控制,并且,不可避免地,有人想要开始向其添加逻辑(例如,如果机器是X则使用10,如果机器是Y则使用15)。在某个时刻,配置文件成为一种特定于域的语言,并且在那时写得很差。

现在我已经漫步到舞台上,这是我的问题:

  1. 配置的真正目的是什么 文件?
  2. 是否应该继续尝试 配置文件简单吗?
  3. 谁应该负责制作 对他们的改变(开发者,用户, 管理员等)?
  4. 它们应该是源控制的 (见问题3)?
  5. 正如我之前所说,我对这些问题的回答不断变化,但现在我在想:

    1. 允许非程序员改变 大块的行为很快
    2. 是的,任何不粗略的事情 grained应该是代码
    3. 用户应负责 配置文件和程序员应该 负责配置 配置文件和代码之间的层 这提供了更细粒度的控制 应用程序
    4. 不,但是细粒度的中间层应该是

18 个答案:

答案 0 :(得分:37)

非常有趣的问题!

我倾向于将配置文件限制为非常简单的“key = value”格式,因为我完全同意您的配置文件可以很快成为完整的程序。例如,任何试图“配置”OpenSER的人都知道你所说的感觉:它不是配置,而是(痛苦的)编程。

如果您需要以您今天无法想象的方式“非配置”应用程序,那么您真正需要的是插件系统。您需要以其他人可以编写新插件的方式开发您的应用程序,并在将来将其挂钩到您的应用程序中。

所以,回答你的问题:

  1. 配置文件的真正目的是什么?

    我想说,允许安装应用程序的人能够调整一些与部署相关的参数,例如主机名,线程数,所需插件的名称以及这些参数的部署参数插件(查看FreeRadius的配置以获取此原理的示例)等。绝对不是表达业务逻辑的地方。

  2. 是否应该尝试保持配置文件简单?

    当然。正如您所说,配置文件中的“编程”非常糟糕。我认为应该避免。

  3. 谁应该负责对其进行更改(开发人员,用户,管理员等)?

    一般情况下,我会说部署应用程序的管理员。

  4. 它们应该是源控制的吗(参见问题3)?

    我通常不会对配置文件本身进行源代码控制,但我执行源代码控制模板配置文件,包含所有参数及其默认值,以及描述它们的功能的注释。例如,如果配置文件名为database.conf,我通常会源代码控制名为database.conf.template的文件。现在我当然在谈论我作为开发人员所做的事情。 作为管理员,我可能希望源代码控制我为每个安装选择的实际设置。例如,我们远程管理几百台服务器,我们需要跟踪它们的配置:我们选择使用源代码控制来执行此操作。


  5. 编辑:虽然我认为上述情况适用于大多数应用程序,但当然总有例外。例如,您的应用程序可能允许其用户动态配置复杂规则。大多数电子邮件客户端允许用户定义用于管理其电子邮件的规则(例如,“来自'john doe'的所有电子邮件并且不会让我在To:字段中被丢弃”)。另一个例子是允许用户定义新的复杂商业报价的应用程序。您还可以考虑像Cognos这样的应用程序,它们允许用户构建复杂的数据库报告。电子邮件客户端可能会为用户提供一个简单的界面来定义规则,这将生成一个复杂的配置文件(甚至可能是一些代码)。另一方面,商业报价的用户定义配置可以以结构化方式保存在数据库中(既不是简单的键=值结构也不是代码的一部分)。而其他一些应用程序甚至可能允许用户使用python或VB或其他一些支持自动化的语言进行编码。换句话说......你的里程可能会有所不同。

答案 1 :(得分:10)

确定。你会有一些想要一个非常简单的配置的用户,你应该给它们。与此同时,你会不断要求“你能添加这个吗?我怎么做配置文件?”,我不明白为什么你不能支持这两个组。

我目前正在处理的项目使用Lua作为其配置文件。 Lua是一种脚本语言,它在这种情况下运行良好。有一个我们default configuration的例子。

你会注意到它主要是key = value语句,其中value可以是Lua的任何内置类型。最复杂的是有列表,它们并不是很复杂(这只是语法问题)。

现在我只是在等待有人询问如何在每次启动时将服务器的端口设置为随机值...

答案 2 :(得分:8)

最近我正在研究一个项目,我意识到我想在配置文件中包含条件 - 以前只是一个非常简单的形式:


key = val
key2 = val
name = `hostname`

我不想写一种迷你语言,因为除非我非常谨慎地做到这一点,否则我不能允许有用的灵活性。

相反,我决定我有两种形式:

  1. 如果文件以“#!”开头并且是可执行的我会解析运行它的结果。

  2. 否则我会按原样阅读

  3. 这意味着我现在可以让人们编写如下所示的“配置文件”:

     #!/usr/bin/perl
    if ( -x /bin/foo ) 
    {
       print <<EOF;
    foo=me
    bar=you
    EOF
    }
    else
    {
       print <<EOF;
    foo=bar
    bar=foo
    EOF
    }
    

    这样,如果用户想要使用它,我就能获得动态配置文件的强大功能,并且不必编写我自己的迷你语言。

答案 3 :(得分:4)

每个(足够长寿命的)配置文件架构最终都会成为一种编程语言。由于您描述的所有含义,配置文件设计者明智地意识到她正在编写一种编程语言并做出相应的计划,这样做是明智的,以免给未来用户带来不良遗产负担。

答案 4 :(得分:3)

你可以转向计算理论来定义什么算作编程语言。如果您的配置文件格式为Turing Complete,那么它合理地算作编程语言。通过这个定义,用于描述Sokoban级别的文件格式被视为编程语言(参见here)。 “图灵完成”下面还有其他级别的复杂性,也可能会计算在内,例如Regular GrammarsPushdown Automata

另一种看待它的方法是许多配置文件只能进行数据标记,而正确的编程语言必须能够实现algorithms。例如,JSON是一种配置文件格式,而ECMA Script是一种编程语言。

答案 5 :(得分:3)

我对配置文件有不同的理念。有关如何运行应用程序的数据仍然是数据,因此属于数据存储,而不是代码(配置文件IMO是代码)。如果最终用户需要能够更改数据,那么应用程序应该提供一个接口来执行此操作。

我只使用配置文件指向数据存储。

答案 6 :(得分:2)

这是我的想法:

  1. 允许轻松修改应用程序的运行时行为。这可以由程序员或非程序员根据需要进行。这可以在开发期间进行,但我经常将配置文件视为一种帮助程序在任何时候都更加灵活的方式。

  2. 是。我认为配置文件应该尽可能简单,因为您可能需要各种选项来控制运行时的不同行为。我更喜欢对配置设置进行分组,并尽可能简化它们。

  3. 取决于改变的内容和原因。如果用户要更改它,应该使用前端来隐藏它们的细节。对于非开发人员来说,情况也是如此。

  4. 我经常控制“默认”配置,但是有办法在实际运行时为每个系统覆盖它。

  5. 至于在配置文件中添加逻辑 - 我会避免这种情况。我认为最好让配置文件切换到应用程序中的逻辑。根据我的经验,配置文件中的行为导致缺乏可维护性和理解。我强烈希望保持配置文件尽可能简单。

答案 7 :(得分:2)

我倾向于同意这个问题的前提。我通过尽早预测会发生这种情况来避免让自己陷入困境,因此从不滚动我自己的配置系统。

  • 我使用操作系统的配置设备(例如plist,或gconf或任何合适的配置),
  • 或者是一个简单的平面文件,可以像现成的INI解析器一样处理。
  • 咬紧牙关,插上一个轻量级的语言解析器,通常是lua,有时候是tcl进入应用程序,
  • 或者将数据存储在SQLite或类似的关系数据库中。

让自己决定与我做出的任何决定一起生活,或者如果我不能,重构使用上述选择之一,更适合应用程序。

重点是,没有任何理由使用自行开发的配置解决方案。首先,用户必须学习新的特定于应用程序的配置格式。另一方面,您可以从使用现成解决方案时免费获得的所有错误修复和更新中受益。最后,功能蠕变将被搁置,因为,实际上,您实际上不能再添加一个功能而不进行重大改造,因为配置系统并非真正掌握在您的手中。

答案 8 :(得分:1)

这取决于您对团队中其他开发人员的看法。您是否正在使用配置文件作为配置文件,或者您正在创建Model Driven应用程序。

配置文件成为编程语言的症状:

  • name = value pair开始相互依赖
  • 你觉得需要流量控制(例如 if(this)而不是
  • 配置文件的文档对于进行进一步开发(而不仅仅是使用应用程序)变得至关重要
  • 在读取config的值之前,需要有一些上下文(即值取决于配置文件本身的外部)

答案 9 :(得分:1)

配置文件总是会成为丑陋,不合逻辑的“完全成熟的编程语言”。设计优秀的编程语言需要艺术和技巧,配置语言转向编程语言往往是可怕的。

一种好的方法是使用设计良好的语言,比如python或ruby,并使用它为您的配置创建DSL。这样,您的配置语言可以在表面上保持简单,但实际上是完全成熟的编程语言。

答案 10 :(得分:1)

我见过配置文件代码的python程序。如果你不需要做任何特殊的事情(条件等),它与其他配置样式没有太大的不同。例如我可以使用以下内容制作文件config.py

num_threads = 13
hostname = 'myhost'
与(比如说)INI文件相比,用户唯一的负担是他们需要在字符串周围添加''。毫无疑问,你可以在其他解释语言中做同样的事情。它可以在必要时为您提供无限的复杂配置文件的能力,但可能会吓到您的用户。

答案 11 :(得分:1)

我相信你的问题非常重要,因为转向“流畅的界面”。许多开发人员已经“看到了关于XML配置应用程序的亮点”。使用XML可能非常冗长且难以正确编辑(特别是如果没有提供架构)。具有流畅的界面允许开发人员在纯文本配置文件(或可能是命令行参数)的某些键值对的帮助下,以特定于域的语言配置应用程序。它还可以非常轻松地设置和配置应用程序的新实例以进行测试。

以下是我对你问题的回答:

  • 配置的真正目的是什么 文件?

配置文件是一种允许用户在运行时自定义其程序行为的方法。

  • 是否应该继续尝试 配置文件简单吗?

理想情况下,我认为配置文件至少应该由流畅的接口来补充以配置程序(这在许多方面都很有用)。如果你确实需要一个配置文件,那么它应该保持非常简单,除了键值对之外别无其他。

  • 谁应该负责制作 对他们的改变(开发者,用户, 管理员等)?

我认为答案取决于您的组织。部署软件的人员应该负责确保软件配置正确。

  • 它们应该是源控制的(参见 问题3)?

我会从其他人那里窃取这个答案:)我喜欢在源代码管理中存储模板配置并根据每个本地用户的需求修改它的想法。机会是一个开发人员的配置文件是另一个开发人员的噩梦,所以最好留下因用户不同而不受源代码控制的影响。拥有模板也是让部署应用程序的人(或其他开发人员)确切地看到配置文件的有效值的好方法。

答案 12 :(得分:0)

配置文件:“我的目的是什么?”
:“配置黄油。”
配置文件:“确定...”
配置文件:“我的目的是什么?”
You :“您配置黄油。”
配置文件:“哦,天哪。”

  1. 配置文件没有“真正目的”。它对您的应用程序有意义。通常,机器之间不同(或可能不同)并且在应用程序运行的中间不变的事物可能应该在配置文件中。其他服务的默认值,端口和地址都是不错的选择。密钥和机密也是不错的选择,但出于安全原因,应与常规配置分开处理。我不同意配置文件的目的是允许进行快速更改。目的应该是允许灵活设置应用程序。如果配置文件是允许这种灵活性的快速简便方法,那就更好了-但您不应该 打算频繁更改配置文件。

  2. 是,不是。您是否应该简化应用程序的代码?是。您应该尝试使编写的所有内容都简单明了。没有比它需要的复杂的多了。您的配置也是如此。但是,这是非常特定于应用程序的。对配置文件中的内容进行硬编码,因为这会使您的配置“太复杂”,这是不好的设计。实际上,试图“保持简单”是配置文件最终变得一团糟的原因。有时最简单的举动就是模块化。这就是为什么应该使用众所周知的通用编程语言而不是某些糟糕的配置语言(请参阅:all "configuration languages" suck)来编写配置文件的原因。

  3. 同样,应该修改配置文件的用户完全取决于应用程序。但是我同意miniquark的观点,无论谁部署应用程序,都应负责配置。

  4. 源代码可以控制一切。源代码控制很棒。您可以非常轻松地将内容回滚,并且拥有所做更改的完整历史记录以及所做更改的记录。那为什么不呢?

答案 13 :(得分:0)

我非常喜欢使用python程序作为配置文件,特别是对于守护进程。除了“配置端口”之外,我喜欢将守护进程完全清空配置。然后,python程序连接到守护程序并继续在守护程序中创建对象并将它们连接在一起以创建所需的配置。一旦设置好所有内容,守护进程就可以独立运行了。当然,好处是你可以使用完整的编程语言编写配置文件,并且因为你已经有办法从另一个程序与守护进程通信,你可以使用它来调试和获取统计数据。主要的缺点是必须处理来自其他程序的消息。

答案 14 :(得分:0)

我们的应用程序代码变得不那么重要了......有脚本,有各种属性可以定义类,方法,方法参数和属性的行为。用户可以定义数据库触发器和数据库约束可能有非常复杂的配置文件。有时用户可以定义XSLT样式表来操作输入和输出,因为我们的系统需要打开(SOA)。还有像BizzTalk这样的东西也需要复杂的配置。用户可以定义复杂的工作流程。

我们必须编写更好的代码来处理这个复杂的环境,因此我们的应用程序代码变得更加重要......

答案 15 :(得分:0)

我会成为逆势者,并且当它体现的不仅仅是XML所代表的时候,它只是一种语言;或者当XML被认为是一种语言时。

或者,大多数配置文件可以被视为类,但只有属性而没有方法。如果没有方法,我认为这不是一种语言。

最终,“语言”是一种软弱的抽象,但是,边缘是模棱两可的。

答案 16 :(得分:0)

微软“奥斯陆”工作的目的之一是允许(但不要求)解决此问题。

  1. 应用程序将附带其包含的任何新组件的模型。它也会使用现有的模型。例如,它可能包含Web服务,因此它可以重用Web服务的系统模型。
  2. 模型将包含描述它们的元数据,包括用于以文本或图形方式访问它们的工具的足够信息。
  3. 部分模型将对应“配置”
  4. 这意味着今天配置文件的等价物可能足够丰富,可以支持其配置的文本和图形编辑。图形工具将提供“Oslo”(代码名称“Quadrant”)。

答案 17 :(得分:0)

是的,配置文件应该很简单。它们本身不应包含“逻辑” - 将它们视为if语句中的表达式列表,而不是整个条件语句。

他们在那里允许用户决定应该使用应用程序中编码的哪个选项,所以不要试图让它们变得复杂,它最终会弄巧成拙 - 你最终可能会写作简单的配置文件,以控制原始配置文件应该如何配置!