Ruby 对象和 JSON 序列化(不带 Rails)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4464050/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:41:58  来源:igfitidea点击:

Ruby objects and JSON serialization (without Rails)

rubyjsonserializationjsonserializer

提问by BuddyJoe

I'm trying to understand the JSON serialization landscape in Ruby. I'm new to Ruby.

我正在尝试了解 Ruby 中的 JSON 序列化格局。我是 Ruby 的新手。

Is there any good JSON serialization options if you are not working with Rails?

如果您不使用 Rails,是否有任何好的 JSON 序列化选项?

That seems to be where this answer goes (to Rails) How to convert a Ruby object to JSON

这似乎是这个答案的去向(到 Rails) How to convert a Ruby object to JSON

The json gem seems to make it look like you have to write your own to_json method. I haven't been able to get to_json to work with arrays and hashes (documentation says it works with these) Is there a reason the json gem doesn't just reflect over the object and use a default serialization strategy? Isn't this how to_yaml works (guessing here)

json gem 似乎让您看起来必须编写自己的 to_json 方法。我无法让 to_json 使用数组和哈希(文档说它适用于这些)是否有原因 json gem 不只是反映对象并使用默认序列化策略?这不是 to_yaml 的工作原理吗(在这里猜测)

回答by david4dev

For the JSON library to be available, you may have to install libjson-rubyfrom your package manager.

要使 JSON 库可用,您可能必须libjson-ruby从包管理器进行安装。

To use the 'json' library:

要使用“json”库:

require 'json'

To convert an object to JSON (these 3 ways are equivalent):

将对象转换为 JSON(这 3 种方式是等效的):

JSON.dump object #returns a JSON string
JSON.generate object #returns a JSON string
object.to_json #returns a JSON string

To convert JSON text to an object (these 2 ways are equivalent):

将 JSON 文本转换为对象(这两种方式是等效的):

JSON.load string #returns an object
JSON.parse string #returns an object

It will be a bit more difficult for objects from your own classes. For the following class, to_json will produce something like "\"#<A:0xb76e5728>\"".

对于您自己的类中的对象,这会更困难一些。对于下面的类, to_json 将产生类似"\"#<A:0xb76e5728>\"".

class A
    def initialize a=[1,2,3], b='hello'
        @a = a
        @b = b
    end
end

This probably isn't desirable. To effectively serialise your object as JSON, you should create your own to_json method. To go with this, a from_json class method would be useful. You could extend your class like so:

这可能是不可取的。为了有效地将您的对象序列化为 JSON,您应该创建自己的 to_json 方法。为此, from_json 类方法将很有用。你可以像这样扩展你的类:

class A
    def to_json
        {'a' => @a, 'b' => @b}.to_json
    end
    def self.from_json string
        data = JSON.load string
        self.new data['a'], data['b']
    end
end

You could automate this by inheriting from a 'JSONable' class:

您可以通过从“JSONable”类继承来自动执行此操作:

class JSONable
    def to_json
        hash = {}
        self.instance_variables.each do |var|
            hash[var] = self.instance_variable_get var
        end
        hash.to_json
    end
    def from_json! string
        JSON.load(string).each do |var, val|
            self.instance_variable_set var, val
        end
    end
end

Then you can use object.to_jsonto serialise to JSON and object.from_json! stringto copy the saved state that was saved as the JSON string to the object.

然后,您可以使用object.to_json序列object.from_json! string化为 JSON 并将保存为 JSON 字符串的保存状态复制到对象中。

回答by Jimothy

Check out Oj. There are gotchas when it comes to converting any old object to JSON, but Oj can do it.

看看奥杰。将任何旧对象转换为 JSON 时会遇到一些问题,但 Oj 可以做到。

require 'oj'

class A
    def initialize a=[1,2,3], b='hello'
        @a = a
        @b = b
    end
end

a = A.new
puts Oj::dump a, :indent => 2

This outputs:

这输出:

{
  "^o":"A",
  "a":[
    1,
    2,
    3
  ],
 "b":"hello"
}

Note that ^ois used to designate the object's class, and is there to aid deserialization. To omit ^o, use :compatmode:

请注意,^o用于指定对象的类,并在那里帮助反序列化。要省略^o,请使用:compat模式:

puts Oj::dump a, :indent => 2, :mode => :compat

Output:

输出:

{
  "a":[
    1,
    2,
    3
  ],
  "b":"hello"
}

回答by Greg Campbell

If rendering performance is critical, you might also want to look at yajl-ruby, which is a binding to the C yajllibrary. The serialization API for that one looks like:

如果渲染性能至关重要,您可能还想查看yajl-ruby,它是 C yajl库的绑定。该序列化 API 如下所示:

require 'yajl'
Yajl::Encoder.encode({"foo" => "bar"}) #=> "{\"foo\":\"bar\"}"

回答by Cir0X

Since I searched a lot myself to serialize a Ruby Object to json:

由于我自己搜索了很多将 Ruby 对象序列化为 json:

require 'json'

class User
  attr_accessor :name, :age

  def initialize(name, age)
    @name = name
    @age = age
  end

  def as_json(options={})
    {
      name: @name,
      age: @age
    }
  end

  def to_json(*options)
    as_json(*options).to_json(*options)
  end
end

user = User.new("Foo Bar", 42)
puts user.to_json #=> {"name":"Foo Bar","age":42}

回答by the Tin Man

What version of Ruby are you using? ruby -vwill tell you.

您使用的是哪个版本的 Ruby?ruby -v会告诉你。

If it's 1.9.2, JSON is included in the standard library.

如果是 1.9.2,则JSON 包含在标准库中

If you're on 1.8.something then do gem install jsonand it'll install. Then, in your code do:

如果你在 1.8.something 上,那么做gem install json它就会安装。然后,在您的代码中执行以下操作:

require 'rubygems'
require 'json'

Then append to_jsonto an object and you're good to go:

然后附加to_json到一个对象,你很高兴去:

asdf = {'a' => 'b'} #=> {"a"=>"b"}
asdf.to_json #=> "{"a":"b"}"

回答by Reactormonk

require 'json'
{"foo" => "bar"}.to_json
# => "{\"foo\":\"bar\"}"

回答by superluminary

If you're using 1.9.2 or above, you can convert hashes and arrays to nested JSON objects just using to_json.

如果您使用的是 1.9.2 或更高版本,则可以仅使用 to_json 将散列和数组转换为嵌套的 JSON 对象。

{a: [1,2,3], b: 4}.to_json

In Rails, you can call to_json on Active Record objects. You can pass :include and :only parameters to control the output:

在 Rails 中,您可以对 Active Record 对象调用 to_json。您可以传递 :include 和 :only 参数来控制输出:

@user.to_json only: [:name, :email]

You can also call to_json on AR relations, like so:

您还可以在 AR 关系上调用 to_json,如下所示:

User.order("id DESC").limit(10).to_json

You don't need to import anything and it all works exactly as you'd hope.

您不需要导入任何东西,一切都如您所愿。

回答by iainbeeston

To get the build in classes (like Array and Hash) to support as_jsonand to_json, you need to require 'json/add/core'(see the readmefor details)

要使内置类(如 Array 和 Hash)支持as_jsonand to_json,您需要require 'json/add/core'(有关详细信息,请参阅自述文件

回答by Aref Aslani

Jbuilderis a gem built by rails community. But it works well in non-rails environments and have a cool set of features.

Jbuilder是由 rails 社区构建的 gem。但它在非 Rails 环境中运行良好,并具有一组很酷的功能。

# suppose we have a sample object as below
sampleObj.name #=> foo
sampleObj.last_name #=> bar

# using jbuilder we can convert it to json:
Jbuilder.encode do |json|
  json.name sampleObj.name
  json.last_name sampleObj.last_name
end #=> "{:\"name\" => \"foo\", :\"last_name\" => \"bar\"}"

回答by ka8725

I used to virtus. Really powerful tool, allows to create a dynamic Ruby structure structure based on your specified classes. Easy DSL, possible to create objects from ruby hashes, there is strict mode. Check itout.

我曾经virtus。真正强大的工具,允许根据您指定的类创建动态 Ruby 结构结构。简单的 DSL,可以从 ruby​​ 哈希创建对象,有严格模式。请出来。