为什么在代码中编写配置数据是个坏主意?

dax*_*xim 22 language-agnostic perl

真实案例(来自caff)举例说明短问题主题:

$CONFIG{'owner'} = q{Peter Palfrader};
$CONFIG{'email'} = q{peter@palfrader.org};
$CONFIG{'keyid'} = [ qw{DE7AAF6E94C09C7F 62AF4031C82E0039} ];
$CONFIG{'keyserver'} = 'wwwkeys.de.pgp.net';
$CONFIG{'mailer-send'} = [ 'testfile' ];
Run Code Online (Sandbox Code Playgroud)

然后在代码中:eval `cat $config`,访问%CONFIG


提供解决一般问题的答案,而不仅仅是示例.

bri*_*foy 27

避免配置代码的原因有很多,我在Mastering Perl的配置章节中介绍了其中的一些原因.

  • 没有配置更改应该带来破坏程序的风险.它肯定不应该冒破坏编译阶段的风险.
  • 人们不应该编辑源代码来获得不同的配置.
  • 人们应该能够共享相同的应用程序而无需使用通用的设置组,而是重新安装应用程序只是为了更改配置.
  • 应该允许人们创建多个不同的配置并批量运行它们,而无需编辑源代码.
  • 您应该能够在不更改代码的情况下在不同设置下测试您的应用程序.
  • 人们不应该学习如何编程以便能够使用您的工具.
  • 您应该只是松散地将配置数据结构绑定到信息源,以便以后更轻松地进行体系结构更改.
  • 您真的想要一个界面而不是在应用程序级别的直接访问.

我在Mastering Perl课程中总结了这一点,告诉人们编程的第一条规则就是创造一种情况,在这种情况下,你可以减少工作,让人们不管你.将配置放入代码中时,您将花费更多时间处理安装问题并响应破坏.除非你喜欢那种东西,否则给人们一种改变设置的方法,而不会给你带来更多的工作.

  • 许多程序员不同意,这就是为什么大多数非程序员讨厌不得不与程序员谈论任何事情. (6认同)

Oes*_*sor 12

$CONFIG{'unhappy_employee'} = `rm -rf /`
Run Code Online (Sandbox Code Playgroud)

  • @Axeman:的确,有些商店的流程很糟糕.如果这是一个仅供少数人使用的内部维护工具,那么严格审查的可能性甚至会更小,并且这种事情的机会也会增加.一个人只是在服务器上的配置文件中附加一行,预定的作业在指定的时间运行,然后,BAM! (7认同)
  • @Axeman:使用简单的文本文件进行配置,这甚至都不是问题. (2认同)

Fru*_*ner 12

这种方法的一个主要问题是您的配置不是非常便携.如果使用Java构建功能相同的工具,则必须重新加载配置.如果Perl和Java变体都使用了简单的key=value布局,例如:

owner = "Peter Palfrader"
email = "peter@peter@palfrader.org"
...
Run Code Online (Sandbox Code Playgroud)

他们可以分享配置.

此外,调用eval配置文件似乎打开此系统攻击.如果他们想要造成一些破坏,恶意的人可以添加到这个配置文件中有什么?您是否意识到配置文件中的任意代码都将被执行?

另一个问题是它非常反直觉(至少对我而言).我希望配置文件可以被一些配置加载器读取,而不是作为可运行的代码执行.这不是那么严重,但可能会让那些不习惯的新开发者感到困惑.

最后,虽然构造的实现不太可能p{...}会发生变化,但如果它们确实发生了变化,这可能无法继续发挥作用.

  • @Gaius:它可能是有效的语法,但这并不意味着它将被"eval"加载它.Java中的.properties文件的格式为`key = value`,但它不像代码那样执行.如果我在Perl中这样做,我会尝试类似的方法逐行解析文件并将数据存储在某种结构中,而不是像执行代码那样简单地执行它. (3认同)

tim*_*eal 6

将配置数据放入已编译的代码中是一个坏主意,因为用户无法轻易更改它.对于脚本,只需确保它与其余部分完全分离并很好地记录.

  • 如果您要在多台计算机上部署脚本,那么您不希望在安装时在每台主机上对其进行编辑.最好将问题分开,并在脚本和配置文件中配置逻辑. (5认同)

Ash*_*ley 6

我感到惊讶的一个原因还没有人提到的是测试.当配置在代码中时,您必须编写疯狂的,扭曲的测试才能安全地进行测试.你最终可以编写复制他们测试的代码的测试,这使得测试几乎无用; 大多只是测试自己,可能漂移,难以维护.

与测试携手并进是提到的部署.当某些东西易于测试时,部署起来会很容易(更好,更容易).

  • 好吧,我提到了.:) (3认同)