我有这段代码:
string
输出真的令人失望:
string
类和JSON对象之间的区别是什么? 如何将类的实例转换为JSON对象?
答案 0 :(得分:4)
有一件事是Ruby class:
来自维基百科的:
在面向对象的编程中,类是可扩展的 程序代码模板,用于创建对象,提供初始值 for state(成员变量)和行为的实现(成员 功能或方法)。
另一个JSON object:
JSON:JavaScript Object Notation。
JSON是一种用于存储和交换数据的语法。
JSON是一种易于使用的XML替代方法。
因此,这是一个众所周知的问题,通常用于从服务器向Web浏览器提供数据,您通常会发送DATA的JSON表示,以便在服务器中将此数据解析为ruby对象。
错误:
http://apidock.com/ruby/JSON/pretty_generate
你只能解析Json的简单对象,你不能解析String,为此你可以在类A中添加方法to_json
irb(main):046:0> JSON.pretty_generate("calimero")
JSON::GeneratorError: only generation of JSON objects or arrays allowed
from /Users/toni/.rvm/gems/ruby-2.2.3@stackoverflow/gems/json-1.8.3/lib/json/common.rb:285:in `generate'
from /Users/toni/.rvm/gems/ruby-2.2.3@stackoverflow/gems/json-1.8.3/lib/json/common.rb:285:in `pretty_generate'
from (irb):59
from /Users/toni/.rvm/rubies/ruby-2.2.3/bin/irb:11:in `<main>'
irb(main):060:0> JSON.pretty_generate([1,2,3])
=> "[\n 1,\n 2,\n 3\n]"
我建议你使用Virtus gem,这澄清了你要解析为JSON的对象的类型,对我来说,知道你转换为JSON的是什么以及你期望的数据是一个好习惯
require 'virtus'
require 'json'
class A
include Virtus.model
attr_accessor :a, :b, :c
attribute :a, Integer
attribute :b, String
attribute :c, Array[Integer]
def initialize(a, b, c)
@a = a, @b = b, @c = c
end
end
irb(main):039:0> a = A.new(1, "a", [1, 2, 3])
=> #<A:0x007fc391882ac8 @b="a", @c=[1, 2, 3], @a=[1, "a", [1, 2, 3]]>
irb(main):040:0> a.attributes
=> {:a=>[1, "a", [1, 2, 3]], :b=>"a", :c=>[1, 2, 3]}
irb(main):053:0> require 'json'
=> true
irb(main):085:0> a.attributes.to_json
=> "{\"a\":[1,\"a\",[1,2,3]],\"b\":\"a\",\"c\":[1,2,3]}"
irb(main):096:0>
答案 1 :(得分:3)
如何将类的实例转换为JSON对象?
Ruby的JSON实现可以序列化/反序列化自定义对象,但是你必须提供详细信息,即
to_json
实例方法,它从对象和json_create
类方法
醇>
以下是使用您的课程的示例:
require 'json'
class A
attr_accessor :a, :b, :c
def initialize(a, b, c)
@a, @b, @c = a, b, c
end
def to_json(*args)
{
JSON.create_id => self.class.name,
'a' => a,
'b' => b,
'c' => c
}.to_json(*args)
end
def self.json_create(h)
new(h['a'], h['b'], h['c'])
end
end
a = A.new(1, 'a', [1, 2, 3])
#=> #<A:0x007f92cc8f37f0 @a=1, @b="a", @c=[1, 2, 3]>
a.to_json
#=> "{\"json_class\":\"A\",\"a\":1,\"b\":\"a\",\"c\":[1,2,3]}"
JSON.create_id
默认为字符串"json_class"
。如果您通过create_additions: true
,它是parse
可识别的特殊标识符:
JSON.parse(a.to_json, create_additions: true)
#<A:0x007ff59c0f2578 @a=1, @b="a", @c=[1, 2, 3]>
如果没有此选项,解析器不会调用A.json_create
并返回普通哈希:
JSON.parse(a.to_json)
#=> {"json_class"=>"A", "a"=>1, "b"=>"a", "c"=>[1, 2, 3]}
调用JSON.pretty_generate(a)
会生成以下输出:
{
"json_class": "A",
"a": 1,
"b": "a",
"c": [
1,
2,
3
]
}
答案 2 :(得分:0)
我会查看序列化数据,并使您的类工作,以便它可以很容易地响应属性。
require 'json'
class A
ATTRS = [:a, :b, :c]
attr_accessor *ATTRS
def initialize(params)
params.each do |k, v|
self.send("#{k}=".to_sym, v)
end
end
def attributes
values = {}
ATTRS.each do |key|
values[key] = self.send(key)
end
values
end
end
a = A.new(a: 1, b: "a", c: [1, 2, 3])
p a
data = a.attributes.to_json
puts data
b = A.new(JSON.parse(data))
p b
为了解释这一点,我使用send为构造函数中的每个属性调用可写方法,这将通过params并设置实例变量值。
然后,attributes方法使用ATTRS常量数组来构建仅此实例属性的对象映射。所以我们序列化它,并反序列化以创建一个新实例。
这几乎是rails的用途,尽管ActiveRecord使用属性哈希来存储传统访问器的属性。