【问题标题】:Ruby YAML problem when deserializing a nested object structure反序列化嵌套对象结构时的Ruby YAML问题
【发布时间】:2010-12-10 01:49:22
【问题描述】:

我有 3 个类具有以下关系:

战场拥有多支队伍。

BattleTeam 有一个成员数组,以及对 Battlefield 的引用。

JaguarBattleTeam 的成员,并且有对其的引用。

如果我对 Jaguar 和 BattleTeam 进行序列化/反序列化,则没有问题。序列化/反序列化 Battlefield 时会出现问题。

序列化它会产生适当的结果,但反序列化它会使 BattleTeam 中的成员为零。

让我告诉你:

>> j = Jaguar.new
=> #<Jaguar:0xa2221f8 @vitality=nil, @spirituality=nil, @log=nil, @name=nil>

#A battleteam might have many members:
>> t = BattleTeam.new
=> #<BattleTeam:0xa21fafc @members=[], @dead_members=[]>

#A battlefield might have many teams:
>> b = Battlefield.new
=> #<Battlefield:0xa2075d8 @teams=[]>

#Add a member to the team
>> t.add_member(j)
=> #<BattleTeam:0xa21fafc @members=[#<Jaguar:0xa2221f8 @vitality=nil, @spirituality=nil, @log=nil, @name=nil, @battle_team=#<BattleTeam:0xa21fafc ...>], dead_members[]

#Add a team to the battlefield
>> b.add_team(t)
=> #<Battlefield:0xa2075d8 @teams=[#<BattleTeam:0xa21fafc @members=[#<Jaguar:0xa2221f8 @vitality=nil, @spirituality=nil, @log=nil, @name=nil, @battle_team=#<BattleTeam:0xa21fafc ...>>], @dead_members=[], @battlefield=#<Battlefield:0xa2075d8 ...>>]>

#Serialize and deserialize the jaguar object (it works as expected):
>> YAML::load j.to_yaml
=> #<Jaguar:0xa1e3cdc @vitality=nil, @spirituality=nil, @log=nil, @name=nil, @battle_team=#<BattleTeam:0xa1e4204 @members=[#<Jaguar:0xa1e3cdc ...>], dead_members[], battlefield#<Battlefield:0xa1e4038 @teams=[#<BattleTeam:0xa1e4204 ...>]

#Serialize and deserialize the battle team object (it words as expected):
>> YAML::load t.to_yaml
=> #<BattleTeam:0xa1d0664 @members=[#<Jaguar:0xa1cfee4 @vitality=nil, @spirituality=nil, @log=nil, @name=nil, @battle_team=#<BattleTeam:0xa1d0664 ...>], dead_members[], battlefield#<Battlefield:0xa1d0470 @teams=[#<BattleTeam:0xa1d0664 ...>]

#Serialize and deserialize the battle team object
#(here the @members array is deserialized as nil, this is not expected!):
>> YAML::load b.to_yaml
=> #<Battlefield:0xa1c370c @teams=[#<BattleTeam:0xa1c33b0 @members=nil, @dead_members=[], @battlefield=#<Battlefield:0xa1c370c ...>]

>> YAML::load(b.to_yaml).teams[0].members
=> nil


#Here is the generated yaml, it looks right, the member is there:
>> puts b.to_yaml
--- &id002 !ruby/object:Battlefield 
teams: 
- &id001 !ruby/object:BattleTeam 
  battlefield: *id002
  dead_members: []

  members: 
  - !ruby/object:Jaguar 
    battle_team: *id001
    log: 
    name: 
    spirituality: 
    vitality: 
=> nil

有人知道这是怎么回事吗?

【问题讨论】:

  • 请不要发布您的完整程序。大多数人不想整天回答你的问题。尝试找到仍然显示症状的最小示例。然后我们可以尝试帮助您了解为什么 ruby​​ 的工作方式与您的预期不同。
  • 事实上,它并不是完整的程序。我省略了类定义。放在那里我可以提供的最简单的示例失败:具有 2 级嵌套的嵌套结构,这就是需要 3 个不同实例的原因。它不会因为 2 就失败。我不知道我怎样才能让它更简单。
  • 我们需要简单的类定义来测试它。
  • 是的,这是一个错误,让一些人重现它。如果您有兴趣复制我会发布代码。

标签: ruby serialization yaml


【解决方案1】:

我真的不太了解 YAML 或序列化/反序列化.. 但是看:

把 b.to_yaml --- &id002 !ruby/object:Battlefield 团队: - &id001 !ruby/object:BattleTeam 战场:*id002 dead_members:[]

成员: - !ruby/object:捷豹 战队:*id001 日志: 姓名: 灵性: 活力: => 无

战场和战队怎么是这样的:

--- &id002 !ruby/object:Battlefield 
- &id001 !ruby/object:BattleTeam 

捷豹看起来像这样:

  - !ruby/object:Jaguar 

id 好像不见了...?

【讨论】:

  • 啊,不,它是正确的。发生这种情况是因为没有其他对象引用 Jaguar 实例,因此它不需要 id。它是在 BattleTeam 实例“内部”创建的。
猜你喜欢
  • 2010-09-21
  • 2013-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-16
  • 2018-09-21
  • 2017-03-10
  • 1970-01-01
相关资源
最近更新 更多