为什么我的ruby类没有转换为json?

时间:2016-01-21 02:19:15

标签: ruby json

我很困惑为什么我的简单ruby对象没有转换为json。

>irb
>
require 'json'

class User
  attr_accessor :name, :age

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

u1 = User.new("a", 1)
u2 = User.new("b", 2)

puts u1.to_json
"\"#<User:0x000001010e9f78>\""

我错过了什么?

我想将这些对象存储到数组集合中,然后将整个集合转换为json。

users = []
users << User.new("a", 1)
users << User.new("b", 2)

users.to_json

注意:这不是使用Rails,只是普通的旧Ruby!

我希望我的json是一个用户对象数组。

[
{"name": "john", "age": 22},
{"name": "john1", "age": 23}
{"name": "john2", "age": 24}
]

2 个答案:

答案 0 :(得分:1)

to_json的默认实现非常简单,显然没有达到预期效果。这是预期的:您需要编写代码来向解释器解释您希望程序的行为方式。

提供to_jsonas_json方法是一种通用标准。第一个后者返回实例的JSON可序列化版本(通常为Hash),后者是实际的JSON输出。

class User
  attr_accessor :name, :age

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

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

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

这是输出

2.3.0 :034 > u1.as_json
 => {:name=>"a", :age=>1}
2.3.0 :035 > puts u1.to_json
{"name":"a","age":1}
 => nil

只需稍加努力,您就可以更改as_json以自动收集所有实例变量。但是,我不鼓励这种方法,因为您最终可能会序列化您并不真正想要共享的敏感属性(如密码)。

答案 1 :(得分:0)

默认情况下,不能将类设为JSON个字符串。您的班级必须拥有to_json方法,因此您可以从此类继承(类型class User < JSONable):

class JSONable
    def to_json
        hash = {}
        self.instance_variables.each do |x|
            hash[x] = self.instance_variable_get x
        end
        return hash.to_json
    end
end

然后,您可以致电to_json,它将正常运作。

测试:

$ irb

irb(main):001:0> require 'json'
=> true
irb(main):002:0> class JSONable
irb(main):003:1>     def to_json
irb(main):004:2>         hash = {}
irb(main):005:2>         self.instance_variables.each do |x|
irb(main):006:3*             hash[x] = self.instance_variable_get x
irb(main):007:3>         end
irb(main):008:2>         return hash.to_json
irb(main):009:2>     end
irb(main):010:1> end
=> nil
irb(main):011:0> class User < JSONable
irb(main):012:1>  attr_accessor :name, :age
irb(main):013:1> 
irb(main):014:1*   def initialize(name, age)
irb(main):015:2>     @name = name
irb(main):016:2>     @age = age
irb(main):017:2>   end
irb(main):018:1> end
=> nil
irb(main):019:0> 
irb(main):020:0* user = User.new("hi",3)
=> #<User:0x007fd6c8af0a90 @name="hi", @age=3>
irb(main):021:0> puts user.to_json
{"@name":"hi","@age":3}