我正在关注 Ruby 教程。我的任务是了解如何将对象保存到 yaml 字符串并使用标准 YAML 模块恢复它们,但我遇到了一个失败的教程代码:
require 'yaml'
class Person
attr_accessor :first_name, :last_name, :patronymic, :password
def initialize(first_name:, last_name:, patronymic:, password:)
@first_name = first_name
@last_name = last_name
@patronymic = patronymic
@password = password
end
end
person = Person.new(
first_name: 'Иван',
last_name: 'Петрович',
patronymic: 'Сидоров',
password: 'qwerty'
)
yaml_str = YAML.dump(person) # интересует именно эта часть кода,
recovered = YAML.load(yaml_str) # чтобы восстановить объект из той же переменной
p recovered.first_name # "Иван"
p recovered.last_name # "Петрович"
p recovered.patronymic # "Сидоров"
p recovered.password # "qwerty"
该程序输出以下内容:
C:/Ruby31-x64/lib/ruby/3.1.0/psych/class_loader.rb:99:in `find': Tried to load unspecified class: Person (Psych::DisallowedClass)
from C:/Ruby31-x64/lib/ruby/3.1.0/psych/class_loader.rb:28:in `load'
from C:/Ruby31-x64/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:424:in `resolve_class'
from C:/Ruby31-x64/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:213:in `visit_Psych_Nodes_Mapping'
from C:/Ruby31-x64/lib/ruby/3.1.0/psych/visitors/visitor.rb:30:in `visit'
from C:/Ruby31-x64/lib/ruby/3.1.0/psych/visitors/visitor.rb:6:in `accept'
from C:/Ruby31-x64/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:35:in `accept'
from C:/Ruby31-x64/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:318:in `visit_Psych_Nodes_Document'
from C:/Ruby31-x64/lib/ruby/3.1.0/psych/visitors/visitor.rb:30:in `visit'
from C:/Ruby31-x64/lib/ruby/3.1.0/psych/visitors/visitor.rb:6:in `accept'
from C:/Ruby31-x64/lib/ruby/3.1.0/psych/visitors/to_ruby.rb:35:in `accept'
from C:/Ruby31-x64/lib/ruby/3.1.0/psych.rb:335:in `safe_load'
from C:/Ruby31-x64/lib/ruby/3.1.0/psych.rb:370:in `load'
from C:/Users/armoy/OneDrive/Documents/selflearning_book/FTP/modules/yaml_load.rb:21:in `<main>'
宝石 psych-4.0.3。YAML 模块的 load 方法的 ri 实用程序似乎没有写任何有趣的东西。
问题不在于
dump
,而在于load
。半年前,psych gem 发生了相当大的变化,方法
load
变得更安全,忘记了如何处理复杂的数据结构。这里有更多关于它的信息。有一个可靠来源的方法
unsafe_load
,使用它最好不要转储对象,因为 yaml 是特定的。如果你需要保存和恢复一个对象,那么它应该首先被序列化为一个散列,然后从一个散列中恢复。例如,添加此方法:
然后像这样保存并阅读: