我有一个YAML文件,其中包含一系列范围作为值:
combat_power:
Bulbasaur: (12.2..1071)
Ivysaur: (19.5..1632)
Venusaur: (32.2..2580)
Charmander: (10.7..955)
Charmeleon: (18.5..1557)
Charizard: (32.5..2602)
Squirtle: (11.4..1008)
Wartortle: (18.9..1582)
Blastoise: (31.7..2542)
Caterpie: (4.3..443)
Metapod: (4.7..477)
Butterfree: (17.2..1454)
尝试将这些范围转换为数组时,我收到错误:<main>': undefined method to_a'
我如何尝试这样做非常简单:
require 'yaml'
data = YAML.load_file('./lib/lists/yamls/combat_power.yml')
print 'Enter a name: '
name = gets.chomp.capitalize
new_data = data['combat_power'][name]
puts new_data.to_a
运行时:
Enter a name: Charmeleon
go.rb:10:in `<main>': undefined method `to_a' for "(18.5..1557)":String (NoMetho
dError)
Did you mean? to_yaml
to_f
to_r
to_i
to_s
to_c
我的问题是,当从YAML文件提供范围键时,如何将范围键转换为数组?您可以使用to_a
函数将范围转换为数组的任何其他方式,但它似乎不起作用。是否有一个我缺少的简单解决方案,或者不允许在YAML文件中使用范围?
答案 0 :(得分:1)
一些事情:
Ruby的YAML实现不会在没有明确告知它的情况下反序列化ruby对象。这既是一个安全特性(一些代码对于反序列化很危险),也是一个不太可能完成的任务(如何知道你打算评估什么?)。因此,要将范围字符串转换为实际的Ruby Range
对象,您需要eval
它:
require 'yaml'
data = YAML.load_file('./yamls.yaml')
print 'Enter a name: '
name = gets.chomp.capitalize
new_data = data['combat_power'][name]
puts eval(new_data).class
# => Range
puts eval(new_data).to_a
请注意,您应该只显示您明确写入的eval
文本 - 来自随机源的eval
代码(例如用户输入)可能是一个严重的安全问题。但只要您只是eval
您编写的YAML文件中的值,就应该没问题。
Ruby不知道如何枚举一系列花车,因此(17.2..1454).to_a
会抛出TypeError
。这是因为口译员可能不知道您是想要增加+1
,+0.1
等。我不确定您希望如何解决此问题,因为解决方案将基于您的数据的含义具体。