2010-08-23 52 views
8

这段代码抛出异常:nil.to_json不能解析回nil?

x = nil 
jsoned = x.to_json 
puts 'x.to_json=' + jsoned.inspect 
puts 'back=' + JSON.parse(jsoned).inspect 

C:/ruby/lib/ruby/1.9.1/json/common.rb:146:in `parse': 706: unexpected token at 'null'  (JSON::ParserError) 
x.to_json="null" 
from C:/ruby/lib/ruby/1.9.1/json/common.rb:146:in `parse' 
from C:/dev/prototyping/appoxy_app_engine/test/temp.rb:10:in `<top (required)>' 
from -e:1:in `load' 
from -e:1:in `<main>' 

那是预期的行为?我会认为这应该工作?

回答

5

该问题不是专门用于nilto_json就像nil或单个字符串这样简单的东西不会产生完整的JSON表示。

例如像JSON.parse("hello".to_json)会产生类似的结果

如果我们有nil一个Hash其价值之一是将编码和正确解码:

>> h = {"name"=>"Mike", "info"=>nil} 
=> {"name"=>"Mike", "info"=>nil} 
>> h.to_json 
=> "{\"name\":\"Mike\",\"info\":null}" 
>> JSON.parse(h.to_json) 
=> {"name"=>"Mike", "info"=>nil} 
+9

你还没有,本身,回答了这个问题。是to_json错误地产生“无效的”JSON,或者是JSON.parse无法解析“有效的”JSON?无论哪种方式,这不应该是红宝石内的行为。我希望序列化/反序列化能够彼此保持一致,而不管底层媒体如何。 – ghayes 2013-06-05 22:52:02

+1

都不:to_json正确生成无效的JSON。当你调用to_json的单个值,例如nil时,你实际上是在说:“告诉我该值如何表示为JSON值。”在某些情况下这是明智的做法,但非对象非数组值仍然不是有效的JSON文本。 – 2013-12-28 15:07:19

1

JSON不喜欢单一的对象,它是真正的序列化集合的物体。如果你尝试这样的事情,你可以看到它确实为零对象生成了有效的JSON,并且可以对它们进行反序列化。

n = JSON.parse(JSON.generate([nil])) # => [nil] 
+1

在Ruby中,Array和Nil都是对象。 – weexpectedTHIS 2014-02-26 18:42:37

14

JSON解析器有一个“quirks模式”,它将解析单个JSON值。

>> nil.to_json 
=> "null" 
>> JSON.parse("null", {:quirks_mode => true}) 
=> nil 

它也适用于其他单值:

>> JSON.parse("12", {:quirks_mode => true}) 
=> 12 
>> JSON.parse("true", {:quirks_mode => true}) 
=> true 
>> JSON.parse(" \"string\" ", {:quirks_mode => true}) 
=> "string" 
+3

为什么ruby JSON lib不会将quirks_mode设置为默认模式? quirks_mode是否有特殊的解析结果? quirks_mode是指默认模式+单个JSON值解析器? – agate 2013-11-19 03:23:58

+2

JSON文本的顶层必须是对象'{}'或数组''''。上面包含的单个值既不是对象也不是数组,因此不是严格解释的JSON文本。怪癖模式允许解析单个值,如上所述 - 它不是默认值,因为它处理非标准情况。 – 2013-12-28 01:25:43