使用YAML有什么好处?

时间:2012-01-28 13:45:42

标签: ruby file eval yaml inspect

当有人提到通过编写inspect输出并通过eval加载来保存信息到外部文件的想法时,我看到许多人会批评这个想法,而是推荐使用YAML。编写inspect的输出有什么问题,为什么YAML更受欢迎?为了人类的可读性,我认为ruby inspectpp格式优于YAML。

3 个答案:

答案 0 :(得分:4)

假设没有覆盖inspect,这有什么用处?:

#<Foo:0xa34feb8 @bar="wat">

与此相比:

--- !ruby/object:Foo
bar: wat

YAML更有可能在非平凡的情况下产生有用的输出。它也是可移植的,可以用作在不同系统之间发送序列化数据的更可靠方式。

答案 1 :(得分:4)

安全是主要关注点。因为eval将运行传递给它的任何代码,恶意黑客可以将代码注入您的数据文件,并控制您的程序。这对于自己的小脚本可能并不重要,但在rails服务器上的ruby中,安全性将非常重要。想象一下,我们有以下代码:

f=File.new("foobar.txt")
f.puts Foo.new.tap {|foo| foo.bar="bork"}.inspect

假设Foo没有覆盖inspect,这会产生这样的结果:

#<Foo:0xff456a5 @bar="bork">

显然,这不是有效的Ruby语法。奇怪的是,eval不会引发任何错误,只会返回nil。这只是一个更糟糕的想法,因为你期望成为Foo的变量现在只是nil(臭名昭着的NoMethodError: undefined method 'bork' for nil:NilClass错误)。

另一个大问题是安全问题。假设您的代码将数据保存到文件中,比方说foo.txt,并将inspect ed哈希映射bar存储到各自的baz es。需要知道这些映射来规划FOO约定的另一个程序会读取eval这个文件。想象一下,这个文件是黑客可以访问它的地方(当你想到它时,几乎可以在任何地方)。如果这些程序在同时存储所有foo财务数据的RoR服务器上运行,则黑客可能会导致大规模混乱。如果这个黑客将代码注入foo.txt,比如说,将恶意病毒下载到系统并安装它,但最后仍然保留了原始程序的哈希,那么它就会被忽视。即使您使用eval $SAFE=4数据,黑客仍然可以通过抛出错误等来破坏foo计划程序的稳定性。

总而言之,虽然inspect - eval方法适用于基本类,例如HashStringArray等,但它取决于在类上给出自己的完全语法表示。对于大多数(如果不是所有)应用程序,使用inspect - eval是个坏主意。 YAML是首选,因为它具有 data 的已定义语法,这意味着混合的可执行代码会导致错误,而不是无意识地执行。此外,许多开发人员使用inspect进行调试,并且不希望对象提供自己的文件转储。

YAML的其他好处是它可以轻松地序列化复杂对象。使用YAML可以很容易地使用复杂的foos和bars对象树,但使用inspect会产生巨大的复杂性。在最后的分析中,这可以被认为是JSON问题 - 由于使用eval而执行的数据中的可执行代码。 inspect对于自己的小实用程序可能没问题,但从不在生产代码中,或者代码可以在广阔的世界范围内开放。

答案 2 :(得分:1)

我推荐YAML,因为:

  1. 我们很容易理解人类,而不仅仅是语言。
  2. 它是一种标准,因此可以跨多种语言移植。
  3. 它支持标量,数组,哈希以及字符串和数字。它还具有一些很酷的命名空间功能和别名,因此您可以重用定义并将数据视为单独的块。
  4. 再次参见#1和#2。这些很重要。