2013-05-01 82 views
1

在CentOS 6.4的RVM下解析JSON与Ruby 1.9.3-p392时遇到了一个奇怪的问题。不是将嵌入对象解码到适当的Ruby类中,而是将该对象作为散列加载。在Ruby 1.9.3-p194它工作正常。Ruby 1.9.3 JSON解析

看看下面的示例:

require 'json' 

class TestMe 
    attr_accessor :me 
    def initialize(option_hash = nil) 
     if option_hash 
      @me = option_hash['me'] 
     end 
     @me ||= "Hello" 
    end 

    def to_json(*a) 
     { 
      JSON.create_id => self.class.name, 
      'data' => { 
       "me" => @me 
      } 
     }.to_json(*a) 
    end 

    def self.json_create(o) 
     new(o['data']) 
    end 
end 

t = TestMe.new 
t.me = "foo" 
t2 = JSON.parse(t.to_json) 
puts t2 

如果我在Ruby 1.9.3-p194运行它,它输出以下:

#<TestMe:0x00000001c877f0> 

如果我运行Ruby 1.9.3-p392相同片段,它输出如下:

{"json_class"=>"TestMe", "data"=>{"me"=>"foo"}} 

的行为p194是我期望和文件意味着什么。为什么不是p392正确解析JSON数据?

+1

我也得到2.0.0中的p392行为,所以这必须是一个预期的改变。 – Linuxios 2013-05-01 00:51:40

+0

我是否错过描述此更改的文档中的任何明显内容?我的意思是......它不是向后兼容的...... – organicveggie 2013-05-01 00:56:32

+1

这可能与最近的[安全通报](https://support.cloud.engineyard.com/entries/23143553-Security-February-11th-2013-Rails - 和 - JSON - 漏洞)和补丁到Rails。这可能是一个非常慎重的改变。默认情况下允许任意实例化Ruby对象,这被认为是一种中立的纯数据传输方法,从来就不是一个好主意。 – tadman 2013-05-01 03:22:00

回答

1

不知道为什么/有什么改变,但我找到了解决办法。基本上,您需要构建一个对象并传入:create_additions选项,而不是仅调用JSON.parse

例子:

p = JSON::Parser.new(json_string, {:create_additions => true}) 
result = p.parse 
0

JSON本身会返回一个散列。有一个扩展它给它增加的能力。尝试使用:

require 'json' 
require 'json/add/core' 

我认为在过去的红宝石JSON一个点自动加载的扩展,但所放的用JSON规范可比性。

“add/core”包含一些to_json方法以基础对象并可能添加恢复自定义对象的功能。我遇到了类似的情况通过JSON传递正则表达式,那就是修复。

我不在我的电脑附近,所以没有确认,但它可能有帮助。

+0

我认为它也被抛弃了,因为从JSON数据中加载任意的Ruby结构是绝对疯狂的。 – tadman 2013-05-01 01:53:50

+0

我同意100%。我添加了一个'to_h'方法来为我的类创建一个散列,然后设置'initialize'作为散列来在另一侧重新创建对象。 – 2013-05-01 04:33:25

1

正如其他人所指出的,这听起来像近期变化的方式JSON对象是unmarshelled。我遇到了一个非常类似的问题here,并得到了一个很好的答案。

+0

啊。这非常有帮助。现在对我来说更有意义。 – organicveggie 2013-05-01 23:54:08