Безопасность является главной заботой.Поскольку 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
может подойти для небольших утилит для вас самих, но никогда в рабочем коде или в коде, открытом для большого среднего мира.