我阅读了一些关于 Yaml 或 yml 文件格式的快速教程。我制作了一个 yaml 文档来表示我的数据。我看到一些 ruby 教程告诉你如何用 ruby 提取 yaml。不幸的是,他们只是打印整个数据或只是键和值。它不符合我的需要。请帮忙。
yaml 文件 -
dev:
game1:
server1:
url: 'dev-game1-a-srv01.gamer.com'
log-path: '/srv/logs'
server2:
url: 'dev-game1-a-srv02.gamer.com'
log-path: '/srv/logs'
game2:
server1:
url: 'dev-game2-a-srv01.gamer.com'
log-path: '/srv/logs'
server2:
url: 'dev-game2-b-srv02.gamer.com'
log-path: '/srv/logs'
server3:
url: 'dev-game2-b-srv01.gamer.com'
log-path: '/srv/logs'
prod:
etc....
如何使用 ruby 代码选择 dev、game2、server 3、url?
使用下面的代码,我得到一个异常 -
require 'yaml'
def server_info
path = 'C:\Code\demo-srv.yml'
yml = YAML::load(File.open(path))
game2 = yml['dev']['game2']
game2.each{|server|
if server['server3']
puts server['server3']['url']
end
}
end
server_info
错误-
server.rb:8:in `[]': can't convert String into Integer (TypeError)
from server.rb:8:in `server_info'
from server.rb:7:in `each'
from server.rb:7:in `server_info'
from server.rb:14
最佳答案
您是否定义了 yaml 数据,或者您只是现有 yaml 文件的使用者?
如果您定义了它,我会用哈希替换服务器数组(请参阅服务器名称前缺少的 -
):
dev:
game1:
server1:
url: 'dev-game1-a-srv01.gamer.com'
log-path: '/srv/logs'
server2:
url: 'dev-game1-a-srv02.gamer.com'
log-path: '/srv/logs'
game2:
server1:
url: 'dev-game2-a-srv01.gamer.com'
log-path: '/srv/logs'
server2:
url: 'dev-game2-b-srv02.gamer.com'
log-path: '/srv/logs'
server3:
url: 'dev-game2-b-srv01.gamer.com'
log-path: '/srv/logs'
然后你可以试试yml['dev']['game2']['server3']['url']
。
注意:不检查丢失/错误的数据。如果 game2
的条目未命中,此代码将引发异常。
所以,也许你应该做类似的事情
if yml['dev'] and yml['dev'].kind_of?(Hash)
if yml['dev']['game2'] and ....
...
else
puts "No dev-branch defined"
end
否则你可以尝试这样的事情:
def server_info
yml = YAML::load(DATA)
yml['dev']['game2'].each{|server|
if server['server3']
p server['server3']['url']
end
}
end
注意(对于两种解决方案):
不检查丢失/错误的数据。此处检查 server['server3']
是否存在。对于真实代码,您还应该检查 dev
和 game2
数据是否存在。
编辑后继续回答:
错误 convert String into Integer
如果您有一个数组但需要一个散列并且您尝试使用字符串访问数组元素,则通常会抛出此错误。
你可以试试下面的代码。有两个变化:
- 第 8 行包含
server
的输出 - 您会看到它是一个数组,没有散列。 第 9+10 行:检查数组并由其两个元素使用(通过#first 和#last)
require 'yaml' def server_info path = 'C:\Code\demo-srv.yml' #~ yml = YAML::load(File.open(path)) yml = YAML::load(DATA) game2 = yml['dev']['game2'] game2.each{|server| p server #-> you get an array if server.first == 'server3' puts server.last['url'] end } end server_info
文件-
dev:
game1:
server1:
url: 'dev-game1-a-srv01.gamer.com'
log-path: '/srv/logs'
server2:
url: 'dev-game1-a-srv02.gamer.com'
log-path: '/srv/logs'
game2:
server1:
url: 'dev-game2-a-srv01.gamer.com'
log-path: '/srv/logs'
server2:
url: 'dev-game2-b-srv02.gamer.com'
log-path: '/srv/logs'
server3:
url: 'dev-game2-b-srv01.gamer.com'
log-path: '/srv/logs'
关于ruby - 使用 ruby 从 yml 文件中提取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29451006/