Ruby对象和JSON序列化(没有Rails)

Bud*_*Joe 68 ruby serialization json jsonserializer

我试图理解Ruby中的JSON序列化格局.我是Ruby的新手.

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

这似乎就是这个答案所针对的(对于Rails) 如何将Ruby对象转换为JSON

json gem看起来好像你必须编写自己的to_json方法.我无法让to_json处理数组和散列(文档说它适用于这些)是否有一个原因json gem不只是反映对象并使用默认的序列化策略?这不是如何to_yaml工作(猜测在这里)

dav*_*dev 105

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

要使用'json'库:

require 'json'
Run Code Online (Sandbox Code Playgroud)

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

JSON.dump object #returns a JSON string
JSON.generate object #returns a JSON string
object.to_json #returns a JSON string
Run Code Online (Sandbox Code Playgroud)

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

JSON.load string #returns an object
JSON.parse string #returns an object
Run Code Online (Sandbox Code Playgroud)

对于来自您自己的类的对象来说会有点困难.对于下面的类,to_json将产生类似的东西"\"#<A:0xb76e5728>\"".

class A
    def initialize a=[1,2,3], b='hello'
        @a = a
        @b = b
    end
end
Run Code Online (Sandbox Code Playgroud)

这可能是不可取的.要有效地将对象序列化为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
Run Code Online (Sandbox Code Playgroud)

您可以通过继承"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
Run Code Online (Sandbox Code Playgroud)

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

  • 这不起作用:`in \`to_json':错误的参数个数(1表示0)(ArgumentError) (6认同)
  • 要从属性名称中删除@:hash [var.to_s.delete"@"] (4认同)
  • 正在寻找一个不需要你在类上编写to_json方法的库.是否有一个你可以继承的课程通过反思给你这个?并在复杂的对象上工作? (3认同)
  • @redolent - 看起来很棒的东西.使用`to_json(options = {})`来修复.见http://stackoverflow.com/questions/11599610/rails-wrong-number-of-arguments-1-for-0-in-to-json-method (2认同)

Jim*_*thy 11

看看Oj.在将任何旧对象转换为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
Run Code Online (Sandbox Code Playgroud)

这输出:

{
  "^o":"A",
  "a":[
    1,
    2,
    3
  ],
 "b":"hello"
}
Run Code Online (Sandbox Code Playgroud)

注意,^o它用于指定对象的类,并有助于反序列化.要省略^o,请使用:compat模式:

puts Oj::dump a, :indent => 2, :mode => :compat
Run Code Online (Sandbox Code Playgroud)

输出:

{
  "a":[
    1,
    2,
    3
  ],
  "b":"hello"
}
Run Code Online (Sandbox Code Playgroud)


Gre*_*ell 8

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

require 'yajl'
Yajl::Encoder.encode({"foo" => "bar"}) #=> "{\"foo\":\"bar\"}"
Run Code Online (Sandbox Code Playgroud)


the*_*Man 7

你使用的是什么版本的Ruby?ruby -v会告诉你的.

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

如果你在1.8.something然后做gem install json,它将安装.然后,在你的代码中做:

require 'rubygems'
require 'json'
Run Code Online (Sandbox Code Playgroud)

然后附加to_json到一个物体,你很高兴:

asdf = {'a' => 'b'} #=> {"a"=>"b"}
asdf.to_json #=> "{"a":"b"}"
Run Code Online (Sandbox Code Playgroud)


Cir*_*r0X 6

因为我自己搜索了很多将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}
Run Code Online (Sandbox Code Playgroud)


Rea*_*onk 4

require 'json'
{"foo" => "bar"}.to_json
# => "{\"foo\":\"bar\"}"
Run Code Online (Sandbox Code Playgroud)