В чем преимущество использования YAML? - PullRequest
4 голосов
/ 28 января 2012

Когда кто-то упоминает идею сохранения информации во внешние файлы, записав вывод inspect и загрузив его через eval, я вижу, что многие люди будут критиковать эту идею и вместо этого рекомендуют использовать YAML.В чем заключается проблема записи вывода inspect, и почему YAML предпочтительнее?Я думаю, что для удобства чтения формат ruby ​​inspect или pp превосходит YAML.

Ответы [ 3 ]

4 голосов
/ 28 января 2012

Безопасность является главной заботой.Поскольку eval будет запускать любой код, переданный ему, злоумышленник может внедрить код в ваш файл данных и взять под контроль вашу программу.Это может быть неважно для небольших скриптов для себя, но на сервере ruby ​​на rails безопасность будет важна.Представьте, что у нас есть следующий код:

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 s этот файл.Представьте, что этот файл находится где-то, где хакер может получить к нему доступ (который, если подумать, находится практически где угодно).Если эти программы работают на сервере RoR, который также хранит все финансовые данные foo, хакер может вызвать массовый хаос.Если этот хакер внедрил код в foo.txt, который, скажем, загрузил вредоносный вирус в систему и установил его, но все же оставил хэш оригинальной программы в конце, он выполнялся бы незамеченным.Даже если вы eval данных с помощью $SAFE=4, хакер все равно может повредить стабильности программы foo строгания, выбрасывая ошибки и т. П.

В целом, хотя inspect - *Подход 1028 * работает для базовых классов, таких как Hash, String, Array и т. Д., Он зависит от класса, чтобы дать точное синтаксическое представление самого себя.Для большинства, если не для всех приложений, плохая идея использовать inspect - eval.YAML предпочтительнее, потому что он имеет определенный синтаксис для data , что означает, что смешанный исполняемый код вызовет ошибки, а не будет выполнен бездумно.Кроме того, многие разработчики используют inspect для отладки и не ожидают, что объект сам выдаст дамп файла.

Другое преимущество YAML заключается в том, что он легко сериализует сложные объекты.Сложное дерево объектов foos и баров было бы легко сделать с YAML, но использование inspect создаст огромную сложность.В конечном итоге это можно рассматривать как проблему JSON - исполняемый код в данных выполняется потому, что использовалось eval.inspect может подойти для небольших утилит для вас самих, но никогда в рабочем коде или в коде, открытом для большого среднего мира.

4 голосов
/ 28 января 2012

Предполагая, что ничто не переопределяет inspect, для чего это нужно?:

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

По сравнению с этим:

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

YAML, скорее всего, даст полезную продукцию при нетривиальных обстоятельствах. Он также переносим и может использоваться как более надежный способ отправки сериализованных данных между разнородными системами.

1 голос
/ 28 января 2012

Я рекомендую YAML, потому что:

  1. Для нас, людей, легко понять, а не только язык.
  2. Это стандарт, поэтому он переносим на несколько языков.
  3. Поддерживает скаляры, массивы, хэши, а также строки и цифры.Он также имеет некоторые интересные возможности и псевдонимы пространства имен, так что вы можете повторно использовать определения и обрабатывать данные как отдельные фрагменты.
  4. См. № 1 и № 2 снова.Это важно.
...