Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.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
如何使用JSON进行Ruby对象序列化_Ruby_Serialization_Json - Fatal编程技术网

如何使用JSON进行Ruby对象序列化

如何使用JSON进行Ruby对象序列化,ruby,serialization,json,Ruby,Serialization,Json,我有这样一个简单容器类的结构(在伪ruby中): 有没有简单的方法在Ruby中将其反序列化为JSON?或者我应该像中那样为每个类创建嵌套的序列化方法 编辑: 在我的特定场景中,我想将一些JSON数据发布到运行Ruby的服务器上,该服务器将提取数据并相应地执行操作 JSON的发送方不一定是Ruby进程,但可能是其他系统的后端。(尽管在我的测试工具中它是Ruby) 因此,我不需要JSON是某种“特定于Ruby”的格式,我只是假设它实际上内置于Ruby中会更容易。对非JSON对象使用Marshal、P

我有这样一个简单容器类的结构(在伪ruby中):

有没有简单的方法在Ruby中将其反序列化为JSON?或者我应该像中那样为每个类创建嵌套的序列化方法

编辑:

在我的特定场景中,我想将一些JSON数据发布到运行Ruby的服务器上,该服务器将提取数据并相应地执行操作

JSON的发送方不一定是Ruby进程,但可能是其他系统的后端。(尽管在我的测试工具中它是Ruby)

因此,我不需要JSON是某种“特定于Ruby”的格式,我只是假设它实际上内置于Ruby中会更容易。

对非JSON对象使用Marshal、PStore或其他Ruby解决方案 人们可能有理由怀疑,为什么像Ruby这样的完全反射式语言不能自动生成JSON并解析任意类

但是,除非您坚持使用JSON类型,否则除了发送或接收另一个正在运行的Ruby之外,没有其他地方可以发送或接收JSON对象。在这种情况下,我怀疑传统的智慧是“忘记JSON,使用原生Ruby接口,比如核心类
Marshal

因此,如果您真的要将这些对象发送到PHP或其他非Ruby的对象,那么您应该使用Array等直接创建支持JSON的Ruby数据结构,然后JSON.generate将直接处理这些数据结构

如果只需要序列化,可以使用
marshall
PStore

更新:啊哈,好的,试试这个:

module AutoJ
  def auto_j
    h = {}
    instance_variables.each do |e|
      o = instance_variable_get e.to_sym
      h[e[1..-1]] = (o.respond_to? :auto_j) ? o.auto_j : o;
    end
    h
  end
  def to_json *a
    auto_j.to_json *a
  end
end
如果您在每个类中包含AutoJ,那么它应该是DTRT

{
  "a": {
    "string_field1": "aa",
    "string_field2": "bb"
  },
  "b": {
    "int_field3": 123,
    "string_field4": "dd"
  }
}
您可能希望将
auto_j
方法更改为返回
h.values
,而不仅仅是
h
,在这种情况下,您会得到:

[
  ["aa", "bb"],
  [123, "dd"]
]
我也有同样的问题(主要是试图创建任意复杂度的JSON字符串),而不是解析它们并将其封送为JSON字符串,我最终编写了自己的简单序列化程序。此代码还转义特殊字符以创建有效的JSON

你所要做的就是:

json  = JSON.new;
jsonString = json.marshal(obj); # Where obj is a Ruby object

下面是我为自定义类实现json的方法

在模块中使用
self.include
有一点神奇。这是2006年的一篇非常好的文章,介绍了模块同时具有实例和类方法

该模块设计为包含在任何类中,以提供
to_json
功能。它拦截
attr_accessor
方法,而不是使用自己的方法,以便对现有类进行最小的更改

to_json
实现就是基于此


谢谢,请参阅我的说明。我当时的印象是,封送闭包会比当前更加自动化。只需小心封送闭包,如
lambdas
Procs
。它们不能。我不知道这是否是一个广泛的列表,可能还有其他结构无法封送。
json  = JSON.new;
jsonString = json.marshal(obj); # Where obj is a Ruby object
module JSONable
  module ClassMethods
    attr_accessor :attributes

    def attr_accessor *attrs
      self.attributes = Array attrs
      super
    end
  end

  def self.included(base)
    base.extend(ClassMethods)
  end

  def as_json options = {}
    serialized = Hash.new
    self.class.attributes.each do |attribute|
      serialized[attribute] = self.public_send attribute
    end
    serialized
  end

  def to_json *a
    as_json.to_json *a
  end
end


class CustomClass
  include JSONable
  attr_accessor :b, :c 

  def initialize b: nil, c: nil
    self.b, self.c = b, c
  end
end

a = CustomClass.new(b: "q", c: 23)
puts JSON.pretty_generate a

{
  "b": "q",
  "c": 23
}