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


90

一段时间以来,我一直在考虑配置文件及其与代码的关系,根据风的日子和方向,我的观点似乎会改变。尽管我继续回到学习Lisp时的最初认识,但越来越多的东西:数据和代码之间几乎没有什么区别。对于配置文件,这似乎是双重事实。当从正确的角度看时,Perl脚本只不过是perl的配置文件。这往往会对诸如QA和分工之类的任务产生相当严重的后果,例如谁应该负责更改配置文件。

从配置文件到完整语言的爬取通常很慢,并且似乎是由对通用系统的渴望所驱动。大多数项目似乎从一些小的配置项目开始,例如在哪里写日志,在哪里查找数据,用户名和密码等。但是随后它们开始增长:功能可以被打开或关闭,操作的时间和顺序开始受到控制,不可避免地,有人要开始向其中添加逻辑(例如,如果机器是X,则使用10;如果机器是Y,则使用15)。在某种程度上,配置文件变成了特定于域的语言,并且在该语言中编写得不​​好。

既然我已经四处奔波,请问以下问题:

  1. 配置文件的真正目的是什么?
  2. 是否应该尝试使配置文件保持简单?
  3. 谁应该负责对它们进行更改(开发人员,用户,管理员等)?
  4. 是否应该对它们进行源代码控制(请参阅问题3)?

正如我之前所说,我对这些问题的答案在不断变化,但现在我在想:

  1. 允许非程序员快速更改大量行为
  2. 是的,任何粗粒度的内容都应该在代码中
  3. 用户应负责配置文件,程序员应负责配置文件和代码之间的配置层,以便对应用程序进行更精细的控制
  4. 不,但是中间的细颗粒应该是

23
当他们变成图灵完成时,当然!
aib

2
正则表达式不是图灵完备的,但仍被视为计算机语言。
Chas。欧文斯2009年

对于某些配置情况,“文件”实际上并不足够。因此,存在像gconf这样的系统。
阿里·阿夫沙尔

1
gconf和文件之间没有真正的区别。Gconf实际上只是一系列目录,其中包含带有内存中表示形式的文件。即使您要启动RDBMS,也可以用一个文件表示它。问题是配置文件中的安全性/良好程度有多高。
Chas。欧文斯

查斯。这就是您访问“文件”的不同之处。以及连接多个客户端时如何处理配置数据的更改。是的,Gconf被表示为磁盘上的文件,但是行为有所不同。如果您的意思是“配置系统中配置数据的复杂性”,请确定。
阿里·阿夫沙尔

Answers:


40

非常有趣的问题!

我倾向于将配置文件限制为非常简单的“键=值”格式,因为我完全同意您的观点,即配置文件可以很快成为成熟的程序。例如,曾经尝试“配置” OpenSER的任何人都知道您在谈论的感觉:这不是配置,而是(痛苦的)编程。

当您需要应用程序以当今无法想象的方式非常“可配置”时,真正需要的是插件系统。您需要以某种方式开发您的应用程序,以便其他人可以编写新的插件并将其挂接到将来的应用程序中。

因此,回答您的问题:

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

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

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

    绝对是 如您所建议,在配置文件中进行“编程”是可怕的。我相信应该避免。

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

    通常,我要说是管理员,谁部署了应用程序。

  4. 是否应该对它们进行源代码控制(请参阅问题3)?

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


编辑:尽管我相信以上对于大多数应用程序都是正确的,但是当然总会有例外。例如,您的应用程序可能允许其用户动态配置复杂的规则。大多数电子邮件客户端允许用户定义其电子邮件管理规则(例如,“来自“ john doe”且在“收件人:”字段中没有我的所有电子邮件都应被丢弃”)。另一个示例是允许用户定义新的复杂商业报价的应用程序。您可能还会考虑使用Cognos之类的应用程序,该应用程序允许其用户构建复杂的数据库报告。电子邮件客户端可能会为用户提供一个简单的界面来定义规则,这将生成一个复杂的配置文件(甚至可能是一些代码)。另一方面,用户定义的商业报价配置可能会以结构化的方式保存在数据库中(既不是简单的键=值结构,也不是代码的一部分)。其他一些应用程序甚至可能允许用户使用python或VB或其他一些具有自动化功能的语言进行编码。换句话说...您的里程可能会有所不同。


10

好。您将有一些用户想要一个非常简单的配置,应该将其提供给他们。同时,您将不断收到“您可以添加它吗?如何在配置文件中进行操作?”的请求,所以我看不到为什么您不能同时支持这两个组。

我目前正在研究的项目使用Lua作为其配置文件。Lua是一种脚本语言,在这种情况下它可以很好地工作。有一个默认配置的示例。

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

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


1
+1使用一种实际的编程语言,这比让一个配置文件中的内容
整整齐齐

+1-这是正确的方法。对于新手来说,Lua确实具有非常“类似于配置”的语法。并允许那些没有的人进行有力的操纵。
安德鲁Y

8

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


key = val
key2 = val
name = `hostname`

我不想编写一个迷你语言,因为除非我做得很仔细,否则我将不会允许有用的灵活性。

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

  1. 如果文件以“#!”开头 并且是可执行文件,我将分析其运行结果。

  2. 否则我会原样阅读

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

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

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


4

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


3

我对配置文件有不同的看法。有关应如何运行应用程序的数据仍然是data,因此属于数据存储区,而不属于代码(IMO的配置文件是代码)。如果最终用户需要能够更改数据,则应用程序应提供一个接口来进行更改。

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


3

您可以转向计算理论来定义什么才算是一种编程语言。如果您的配置文件格式为Turing Complete,则可以合理地算作一种编程语言。根据此定义,描述Sokoban级别的文件格式算作一种编程语言(请参见此处)。图灵完成以下还有其他复杂程度,例如常规文法下推自动机也可能算在内

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


2

这是我的想法:

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

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

  3. 取决于更改的内容和原因。如果用户要更改它,则应使用前端将其隐藏在细节中。一般而言,非开发人员通常也是如此。

  4. 我经常使用源代码控制“默认”配置,但是有一种方法可以针对每个系统在实际运行时覆盖它。

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


2

我倾向于同意这个问题的前提。我通过尽早预测会发生这种情况来避免惹上麻烦,因此请不要滚动自己的配置系统。

  • 我要么使用操作系统的配置功能(例如plist或gconf或其他合适的方法),
  • 或简单的平面文件,可以通过现成的INI解析器处理。
  • 咬一下子弹,然后插入轻量级的语言解析器(通常是lua,有时是tcl)插入应用程序,
  • 或将数据存储在SQLite或类似的关系数据库中。

并辞职以接受我做出的任何决定,或者,如果我做不到,请重构以使用更适合该应用程序的上述选择之一。

关键是,实际上没有任何理由使用自主开发的配置解决方案。一方面,您的用户很难学习一种新的,特定于应用程序的配置格式。另外,使用现成的解决方案时,您会从许多免费的错误修复程序和更新中受益。最后,功能蠕变得到了解决,因为,实际上,您不能在没有进行大修的情况下添加一个功能,因为配置系统根本就不在您手中。


1

这取决于您与团队中其他开发人员的同意。您是将配置文件用作配置文件,还是正在创建模型驱动的应用程序。

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

  • 名称=值对开始相互依赖
  • 您觉得需要进行流量控制(例如,如果(this)大于那个
  • 配置文件的文档对于进行进一步的开发至关重要(而不仅仅是使用应用程序)
  • 在读取config中的值之前,它需要具有一定的上下文(即,值取决于配置文件本身外部的某些内容)

1

配置文件无可避免地成为丑陋,不合逻辑的“成熟编程语言”。设计好的编程语言需要技巧和技能,而将配置语言转变为编程语言的过程往往令人恐惧。

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


1

我相信您的问题与“流利的界面”相关,非常相关。关于XML配置的应用程序,许多开发人员已经“见识了”。使用XML可能非常冗长且难以正确编辑(尤其是如果未提供模式)。具有流畅的界面允许开发人员借助来自纯文本配置文件(或命令行参数)的一些键值对,以特定于域的语言配置应用程序。它还使设置和配置应用程序的新实例以进行测试或其他操作变得非常容易。

这是我对您问题的回答:

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

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

  • 是否应该尝试使配置文件保持简单?

理想情况下,我认为配置文件至少应通过流畅的界面进行补充以配置程序(这在许多方面都非常有用)。如果确实需要配置文件,则应使其非常简单,除了键值对。

  • 谁应该负责对它们进行更改(开发人员,用户,管理员等)?

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

  • 是否应该对它们进行源代码控制(请参阅问题3)?

我会从其他人那里窃取此答案:)我喜欢将模板配置存储在源代码管理中并针对每个本地用户的需求对其进行修改的想法。一个开发人员的配置文件很可能是另一个开发人员的噩梦,因此最好将因用户而异的内容置于源代码控制之外。拥有模板也是让部署应用程序的人员(或其他开发人员)准确了解哪些值对配置文件有效的好方法。


1

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

num_threads = 13
hostname = 'myhost'

与(例如)INI文件相比,给用户带来的唯一负担就是他们需要在字符串前后加上“”。毫无疑问,您可以使用其他解释语言执行相同的操作。如果需要,它使您可以无限复杂地配置文件,这有可能会吓users用户。


0

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

它们在那里,允许用户决定应使用应用程序内编码的哪个选项,因此不要试图使其变得复杂,否则最终会自欺欺人-您可能最终会编写简单的配置文件控制否则应如何配置原始配置文件!


0

Microsoft的“奥斯陆”工作的目的之一是允许(尽管不是必需)解决此问题。

  1. 应用程序将附带其包含的任何新组件的模型。它还将使用现有模型。例如,它可能包括一个Web服务,因此它可以重用Web服务的系统模型。
  2. 这些模型将包含描述它们的元数据,包括足够的信息以供工具以文本或图形方式访问它们。
  3. 部分模型将对应于“配置”

这意味着当今等效的配置文件可能足够丰富,可以支持对其配置进行文本和图形编辑。图形工具将随“ Oslo”一起提供(代号为“ Quadrant”)。


0

我将成为逆势主义者,并提出它只是一种语言,它包含的内容超出了XML所能代表的范围;否则,当XML被认为是一种语言时。

另外,大多数配置文件都可以认为是类,但只有属性而没有方法。没有方法,我不认为这是一种语言。

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


0

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

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


0

我非常喜欢将python程序用作配置文件,尤其是对于守护程序。我喜欢采取使守护程序完全清空配置的方法,除了“配置端口”。然后,python程序连接到守护程序,并继续在守护程序中创建对象,并将它们连接在一起以创建所需的配置。设置完所有内容后,就可以让该守护程序自己运行。当然,这样做的好处是,您可以使用成熟的编程语言来编写配置文件,并且由于已经可以从另一个程序与守护程序进行通讯,因此可以将其用于调试和获取统计信息。主要缺点是必须随时处理来自另一个程序的消息。


0

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

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

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.