Проблема Ruby YAML при десериализации вложенной структуры объекта

У меня есть 3 класса, которые имеют следующие отношения:

В Battlefield есть множество команд.

BattleTeam содержит множество участников и ссылку на Battlefield.

Jaguar является членом BattleTeam и имеет ссылку на нее.

Если я сериализую/десериализую 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

Кто-нибудь знает, что с этим не так?


person zenw0lf    schedule 26.10.2009    source источник
comment
Пожалуйста, не публикуйте свою полную программу. Большинство людей не хотят тратить весь день, отвечая на ваш вопрос. Попробуйте найти самый маленький пример, который все еще показывает симптомы. Тогда мы можем попытаться помочь вам понять, почему ruby ​​работает не так, как вы ожидали.   -  person johannes    schedule 27.10.2009
comment
На самом деле это не полная программа. Я пропустил определения классов. Просто поместите туда простейший пример, который я мог предоставить, который терпит неудачу: вложенная структура с 2 уровнями вложенности, поэтому необходимы 3 разных экземпляра. Это не подведет всего 2. Я не знаю, как я мог бы сделать это проще.   -  person zenw0lf    schedule 27.10.2009
comment
Нам нужны простые определения классов, чтобы проверить это.   -  person Ken Bloom    schedule 18.12.2009
comment
И да, это баг, некоторые воспроизвели его. Если вы заинтересованы в воспроизведении, я опубликую код.   -  person zenw0lf    schedule 18.12.2009


Ответы (1)


Я действительно мало знаю о YAML или сериализации/десериализации. Но посмотрите:

ставит b.to_yaml --- &id002 !ruby/object:Battlefield team: - &id001 !ruby/object:BattleTeam поле боя: *id002 dead_members: []

участники: - !ruby/object:Jaguar battle_team: *id001 log: name: Spiritity: Vitality: => nil

Почему поле боя и боевая команда выглядят так:

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

А Ягуар выглядит вот так:

  - !ruby/object:Jaguar 

Идентификатор, кажется, отсутствует...?

person Trevoke    schedule 17.12.2009
comment
А, нет, это правильно. Это происходит потому, что ни один другой объект не ссылается на экземпляр Jaguar, поэтому ему не нужен идентификатор. Он создается внутри экземпляра BattleTeam. - person zenw0lf; 18.12.2009