Ruby - 为什么JSON的反序列化输出的是Array而不是我的类?

时间:2017-02-05 20:09:57

标签: json ruby serialization

我在Odin Project做一个简单的刽子手游戏,可以选择保存和加载游戏。

我已经用JSON序列化了我的类并将其保存到文件中,其内容如下所示:

{"@password":["p","r","o","f","u","s","e","l","y"],"@password_checked":["_","_","_","_","u","_","_","_","_"],"@chances":8,"@picked_letters":["u","a"]}

我的序列化和反序列化方法来自https://www.sitepoint.com/choosing-right-serialization-format/,它们看起来像这样:

 require 'json'

module BasicSerializable

  @@serializer = JSON

  def serialize
    obj = {}
    instance_variables.map do |var|
      obj[var] = instance_variable_get(var)
    end

    @@serializer.dump obj
  end

  def unserialize(string)
    obj = @@serializer.parse(string)
    obj.keys.each do |key|
      instance_variable_set(key, obj[key])
    end
  end
end

我的反序列化代码看起来像这样

file = File.new(game_to_load, 'r')
serialized_object = file.gets     # serialized_object is the file from above
p @password.class                           #=> Password
@password = unserialize(serialized_object)
p @password.class                           #=> Array
p @password     #=> ["@password", "@password_checked", "@chances", "@picked_letters"]

问题在于我无法弄清楚为什么serialized_object的反序列化正在输出数组。如何使用保存在开头提到的文件中的对象状态输出我的类?

1 个答案:

答案 0 :(得分:1)

您没有在unserialize对象上调用@password,因此将在当前对象上调用它。你没有显示那是什么,但我想这是一个数组。

相反,您需要@password.unserialize

一些说明......

由于unserialize更改了对象并吹走了现有数据,因此它可能应为unserialize!

请注意,Ruby已经有Marshal class进行序列化和反序列化。它是二进制格式,而不是JSON。

将您的密码存储为明文是 真的 糟糕的主意。密码永远不应该存储 EVER ,只能存储它们的哈希值。良好的散列意味着如果密码文件被盗,攻击者可能会遇到额外的障碍。如果你做对了,他们几乎不会破碎。

请参阅Salted Password Hashing - Doing it Right