Ruby序列化数据结构

时间:2014-07-16 17:57:21

标签: ruby json serialization

我正在尝试从Ruby序列化复杂的JSON结构。我不是在使用Rails,但在Ruby上我已经足够新了,我不确定这是否重要。 另一端的API期待像这样的

{ "command" : {
   "param" : { "field" : "val", "otherField":"otherVal" },
   "param" : { "field" : "val", "otherField":"otherVal" },
   "param" : { "field" : "val", "otherField":"otherVal" }
    }
}

序列化之前命令保持什么样的ruby对象?它不是一个数组,因为会有另一级方括号(见下面的例子)。而且我是ruby的新手,但是不要认为你可以在哈希中拥有多个具有相同名称的对象。

Backstory:因为散列和数组在Ruby中很好地序列化为json,所以我期待这样的事情:

Ary = Array.new
Ary.push (param.new)
Ary.push (param.new)
Ary.push (param.new)
wrappedCmd = { "command" => Ary }
Oj.dump(wrappedCmd)

但这会产生:

{ "command" : [
   "param" : { "field" : "val", "otherField":"otherVal" },
   "param" : { "field" : "val", "otherField":"otherVal" },
   "param" : { "field" : "val", "otherField":"otherVal" }
    ]
}

我已经确认第一种格式是预期的,因为手动构造的序列化会通过,而第二种格式会产生无效的格式错误。

2 个答案:

答案 0 :(得分:0)

不同之处在于第一个包含散列,第二个包含一个数组。所以你应该做这样的事情:

cmd = {}
cmd['param1'] = Param.new
cmd['param2'] = Param.new
cmd['param3'] = Param.new
Oj.dump("command" => cmd)

实际上,哈希不能有重复的密钥名称。听起来你的API没有使用正确的JSON?

答案 1 :(得分:0)

如果您尝试解析该初始JSON字符串,会发生以下情况:

require 'json'

foo = JSON['{ "command" : {
   "param" : { "field" : "val", "otherField":"otherVal" },
   "param" : { "field" : "val", "otherField":"otherVal" },
   "param" : { "field" : "val", "otherField":"otherVal" }
    }
}']

foo # => {"command"=>{"param"=>{"field"=>"val", "otherField"=>"otherVal"}}}

所以,我们知道这是无效的。我怀疑JSON只是一个写得不好的例子。由于继续发送相同的"param"是没有意义的,因此它们应该是不同的参数名称。

关于你的代码:它不是惯用的Ruby。

Ary = Array.new
Ary.push (param.new)
Ary.push (param.new)
Ary.push (param.new)
wrappedCmd = { "command" => Ary }

我们写得像:

ary = []
ary << param.new
ary << param.new
ary << param.new
wrapped_cmd = { "command" => ary }

甚至更简单:

ary = [
  param.new,
  param.new,
  param.new,
]
wrapped_cmd = { "command" => ary }

甚至:

wrapped_cmd = { 
  "command" => [
      param.new,
      param.new,
      param.new,
  ] 
}
  • 常量以大写字母开头,变量以小写字母开头,因此请使用ary代替Ary
  • 通常我们使用[]来初始化空数组而不是Array.new。这是一个可读性的东西。
  • 通常我们使用<<将元素附加到数组上。再一次,它是一个可读性的东西。
  • Ruby中的变量是用snake_case编写的,而不是camelCase,以便再次阅读。它比easyItToReadCamelCase更容易_to_to_read_snake_case。