Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 使用YAML的好处是什么?_Ruby_File_Eval_Yaml_Inspect - Fatal编程技术网

Ruby 使用YAML的好处是什么?

Ruby 使用YAML的好处是什么?,ruby,file,eval,yaml,inspect,Ruby,File,Eval,Yaml,Inspect,当有人提到通过编写inspect输出并通过eval加载来将信息保存到外部文件的想法时,我发现很多人会批评这个想法,转而建议使用YAML。编写inspect的输出有什么问题,为什么更喜欢YAML?对于人类可读性,我认为rubyinspect或pp格式优于YAML。假设没有任何内容覆盖inspect,这有什么用 #<Foo:0xa34feb8 @bar="wat"> YAML更有可能在非平凡的情况下产生有用的输出。它还具有可移植性,可以作为在不同系统之间发送序列化数据的更可靠方式。安全

当有人提到通过编写
inspect
输出并通过
eval
加载来将信息保存到外部文件的想法时,我发现很多人会批评这个想法,转而建议使用YAML。编写
inspect
的输出有什么问题,为什么更喜欢YAML?对于人类可读性,我认为ruby
inspect
pp
格式优于YAML。

假设没有任何内容覆盖
inspect
,这有什么用

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

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

安全性是主要问题。由于
eval
将运行传递给它的任何代码,恶意黑客可能会将代码注入您的数据文件,并控制您的程序。这对于您自己的小脚本来说可能并不重要,但在RubyonRails服务器中,安全性将非常重要。假设我们有以下代码:

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:nil:NilClass
错误的未定义方法'bork')

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

总而言之,尽管
inspect
-
eval
方法适用于基本类,如
散列
字符串
数组
等,但它取决于类自身的精确语法表示。对于大多数应用程序,如果不是所有应用程序,使用
inspect
-
eval
是个坏主意。YAML是首选的,因为它有一个定义的数据语法,这意味着混合在其中的可执行代码将导致错误,而不是盲目地执行。此外,许多开发人员使用
inspect
进行调试,并且不希望对象本身提供文件转储


YAML的其他好处是它可以轻松地序列化复杂对象。使用YAML可以很容易地创建一个由foos和bar组成的复杂对象树,但是使用
inspect
将产生巨大的复杂性。归根结底,这可以看作是JSON问题——因为使用了
eval
而执行的数据中的可执行代码<代码>检查
可能适合您自己使用的小型实用程序,但绝不适用于生产代码或面向广大用户的代码。

我推荐YAML,因为:

  • 这对我们人类来说很容易理解,而不仅仅是一种语言
  • 它是一个标准,因此可以跨多种语言移植
  • 它支持标量、数组、哈希、字符串和数字。它还具有一些很酷的名称空间功能和别名,因此您可以重用定义并将数据视为单独的块
  • 再看第1和第2页。这些都很重要
  • 我明白2,但请看我的问题1。
    #<Foo:0xff456a5 @bar="bork">