我有一个YAML文件,如下所示:
--- !ruby/object:Hi
num: 1
--- !ruby/object:Hi
num: 2
和我的红宝石代码:
require 'yaml'
class A
attr_accessor :num
def initialize num
@num=num
end
end
a=A.new 1
b=A.new 2
File.open 'test.yml', 'r+' do |f|
f.write YAML.dump a
f.write YAML.dump b
f.seek(0)
#c=obj a
#d=ojb b
end
我想让p c和p d输出如下:
#<A:0x00000 @num=1>
#<A:0x00001 @num=2>
答案 0 :(得分:3)
我不确定为什么某些人如此坚定,因为YAML格式为explicitly designed to accommodate that particular use case,因此您不能将多个YAML文档放在一个文件中。在Ruby中,您可以使用YAML.load_stream
解析多个文档,它将反序列化的对象作为数组返回:
require "yaml"
class A
attr_accessor :num
def initialize num
@num = num
end
end
a = A.new 1
b = A.new 2
File.open "test.yml", "r+" do |f|
f.write YAML.dump(a)
f.write YAML.dump(b)
f.seek(0)
c, d = YAML.load_stream(f)
p c
# => #<A:0x000055d423387cd0 @num=1>
p d
# => #<A:0x000055d423387528 @num=2>
end
您也可以将一个块传递给YAML.load_stream
,在这种情况下,它会为每个文档调用:
YAML.load_stream(f) do |obj|
p obj.num
end
# => 1
# => 2
您可以在repl.it:https://repl.it/@jrunning/FavorableElderlyAddition
中查看两者答案 1 :(得分:-1)
我更喜欢将对象写入单独的文件,但您的序列化方式也可以。 以下是您案例的解决方案;
RUBY_OBJECT = '--- !ruby/object:'
def load_objects(file_content)
object_contents = file_content.split(RUBY_OBJECT)
object_contents.map do |object_content|
YAML.load(RUBY_OBJECT + object_content)
end.compact
end
##########
File.open 'test.yml', 'r+' do |f|
f.write YAML.dump(a)
f.write YAML.dump(b)
f.seek(0)
file_content = f.read
c, d = *load_objects(file_content)
puts c
puts d
end
您还可以对文件内容运行regex以获取单个对象定义。
如果使用一个文件进行序列化是一项严格的要求,您可以像这样将一组对象序列化到该文件中;
require 'yaml'
class A
attr_accessor :num
def initialize(num)
@num = num
end
end
a = A.new(1)
b = A.new(2)
File.open('test.yml', 'w+') do |f|
f.write YAML.dump([a, b])
end
objects = YAML.load_file('test.yml')
答案 2 :(得分:-2)
object = JSON.parse(YAML::load_file("./test.yaml").to_json, object_class: OpenStruct)
不是100%确定这些格式将会出现,但它会为您提供一个好的起点