1

我正在尝试在我的沙盒应用程序中构建一些基本的对象持久性(保存游戏、加载游戏)。

我正在使用 YAML 将对象转储到文件中,然后我想恢复它们。我有两类不同的实例化对象,它们是这样写的,看起来都很好:

---
- !ruby/object:Game::Room
    reference: :largecave
    name: Large cave
    description: a large empty cave
    connections:
    :west: :smallcave
    :south: :waterfall
- !ruby/object:Game::Room
    reference: :smallcave
    name: Small cave
    description: a small cave
    connections:
    :east: :largecave
- !ruby/object:Game::Room
    reference: :waterfall
(... etc)
---
- !ruby/object:Game::GameObject
    reference: :key
    name: Key
    description: A small key
    room: :smallcave
- !ruby/object:Game::GameObject
    reference: :bowl
(....etc)

问题在于试图恢复和填充两个不同的对象数组:

YAML.load(datastore.read)

工作正常,但只适用于一类对象,我试过 select 方法,像这样,但没有成功:

@rooms = datastore.select("!ruby/object:Game::Room")
@objects = datastore.select("!ruby/object:Game::GameObject") 
4

1 回答 1

2

作为数据可用性的建议,我建议为您的类创建一些方法来生成对象内容的哈希值。这样,您就可以存储通用的哈希值的 YAML 表示,而不是 Ruby 对象,后者只能在 Ruby 中使用,而不能在其他语言中使用。

我会放弃在您的 YAML 文件中创建多个文档,并会使用以下内容:

require 'pp'
require 'yaml'

places =   [
  {
    reference: :largecave,
    name: 'Large cave',
    description: 'a large empty cave',
    connections: {
      west: :smallcave,
      south: :waterfall
    }
  },
  {
    reference: :smallcave,
    name: 'Small cave',
    description: 'a small cave',
    connections: {
      east: :largecave
    }
  },
  {
    reference: :waterfall
  }
]

things = [
  {
    reference: :key,
    name: 'Key',
    description: 'A small key',
    room: :smallcave
  },
  {
    reference: :bowl
  }
]

data = [
  places,
  things
]

puts data.to_yaml

哪个输出:

---
- - :reference: :largecave
    :name: Large cave
    :description: a large empty cave
    :connections:
      :west: :smallcave
      :south: :waterfall
  - :reference: :smallcave
    :name: Small cave
    :description: a small cave
    :connections:
      :east: :largecave
  - :reference: :waterfall
- - :reference: :key
    :name: Key
    :description: A small key
    :room: :smallcave
  - :reference: :bowl

通过 YAML-land 来回查看数据:

places, things = YAML.load(data.to_yaml)

=> [[{:reference=>:largecave,
  :name=>"Large cave",
  :description=>"a large empty cave",
  :connections=>{:west=>:smallcave, :south=>:waterfall}},
  {:reference=>:smallcave,
  :name=>"Small cave",
  :description=>"a small cave",
  :connections=>{:east=>:largecave}},
  {:reference=>:waterfall}],
[{:reference=>:key,
  :name=>"Key",
  :description=>"A small key",
  :room=>:smallcave},
  {:reference=>:bowl}]]

pp places

[{:reference=>:largecave,
  :name=>"Large cave",
  :description=>"a large empty cave",
  :connections=>{:west=>:smallcave, :south=>:waterfall}},
{:reference=>:smallcave,
  :name=>"Small cave",
  :description=>"a small cave",
  :connections=>{:east=>:largecave}},
{:reference=>:waterfall}]

pp things

[{:reference=>:key,
  :name=>"Key",
  :description=>"A small key",
  :room=>:smallcave},
{:reference=>:bowl}]

您还可以利用YAML::Store并这样做:

require 'yaml/store'
require 'pp'

store = YAML::Store.new('objects.store')
store.transaction do
  store['places'] = places
  store['things'] = things
end

places = things = nil

store.transaction(true) do
  places = store['places']
  things = store['things']
end

pp places
pp things

看起来像:

[{:reference=>:largecave,
  :name=>"Large cave",
  :description=>"a large empty cave",
  :connections=>{:west=>:smallcave, :south=>:waterfall}},
{:reference=>:smallcave,
  :name=>"Small cave",
  :description=>"a small cave",
  :connections=>{:east=>:largecave}},
{:reference=>:waterfall}]

[{:reference=>:key,
  :name=>"Key",
  :description=>"A small key",
  :room=>:smallcave},
{:reference=>:bowl}]

YAML::Store 将为您在磁盘上创建 YAML 文件:

---
places:
- :reference: :largecave
  :name: Large cave
  :description: a large empty cave
  :connections:
    :west: :smallcave
    :south: :waterfall
- :reference: :smallcave
  :name: Small cave
  :description: a small cave
  :connections:
    :east: :largecave
- :reference: :waterfall
things:
- :reference: :key
  :name: Key
  :description: A small key
  :room: :smallcave
- :reference: :bowl

这基本上是一个哈希,嵌入数据的关键在哪里places和是。things

将“Adventure”的配置存储在 YAML 文件中可能会变得笨拙,因此您可能希望最终考虑使用类似Sequel和 SQLite 数据库的东西。您仍然可以以通用格式存储数据,但它也可以设置为快速随机访问,并且不需要包含在内存中。

于 2012-10-19T16:28:42.233 回答