我需要在rails上下文中使用YAML序列化ruby Range
。
我想检查整数范围和字符串范围是否正确序列化。
这是我的测试:
# classic irb
require 'yaml' # => true
YAML::VERSION # => "0.60"
YAML.dump(1..2) # => "--- !ruby/range \nbegin: 1\nend: 2\nexcl: false\n"
YAML.dump("1".."2") # => "--- !ruby/range \nbegin: \"1\"\nend: \"2\"\nexcl: false\n"
两个输出是完全不同的,所以我前进并在我的rails应用程序中编码。
然而,似乎在rails上下文中,ruby忘记了如何正确序列化一系列整数!
# ./script/rails console
Rails::VERSION::STRING # => "3.0.15"
RUBY_VERSION # => "1.8.7"
YAML::VERSION # => "0.60"
YAML.dump(1..2) # => "--- !ruby/range\n begin: 1\n end: 2\n excl: false"
YAML.dump("1".."2") # => "--- !ruby/range\n begin: 1\n end: 2\n excl: false"
# The two outputs are identical, the distinction between integers and strings is lost!
rails上的ruby和ruby似乎都使用相同版本的YAML库。 如果我没有弄错,我的ruby版本不支持在多个编码器引擎之间切换。
我有几个问题:
感谢您的帮助。
答案 0 :(得分:0)
范围是Ruby内部,而不是像整数或字符串的YAML基类型。而不是按原样编码范围,使用其起点和终点并重建接收端的范围。
我用的是:
[1] (pry) main: 0> range = 0..1
=> 0..1
[2] (pry) main: 0> require 'yaml'
=> true
[3] (pry) main: 0> YAML.dump(range)
=> "--- !ruby/range\nbegin: 0\nend: 1\nexcl: false\n"
[4] (pry) main: 0> YAML.dump({'min' => range.min, 'max' => range.max})
=> "---\nmin: 0\nmax: 1\n"
然后我可以使用类似的东西在接收端重新创建范围:
Range.new(*YAML.load(YAML.dump({'min' => range.min, 'max' => range.max})).values)
=> 0..1
或如果您不确定'min'
和'max'
的顺序是否正确,请执行以下操作:
[19] (pry) main: 0> Range.new(*YAML.load(YAML.dump({'min' => range.min, 'max' => range.max})).values_at('min', 'max'))
=> 0..1
添加有关Ruby 1.9.3+序列化字符范围的一些信息:
[2] (pry) main: 0> range = '0'..'1'
=> "0".."1"
[3] (pry) main: 0> YAML.dump(range)
=> "--- !ruby/range\nbegin: '0'\nend: '1'\nexcl: false\n"
[5] (pry) main: 0> RUBY_VERSION
=> "1.9.3"
再次使用1.9.2 +:
[2] (pry) main: 0> range = '0'..'1'
=> "0".."1"
[3] (pry) main: 0> YAML.dump(range)
=> "--- !ruby/range \nbegin: \"0\"\nend: \"1\"\nexcl: false\n"
[4] (pry) main: 0> RUBY_VERSION
=> "1.9.2"
并且,变通方法维护范围开始/结束类型:
[6] (pry) main: 0> Range.new(*YAML.load(YAML.dump({'min' => range.min, 'max' => range.max})).values_at('min', 'max'))
=> "0".."1"
在这两种情况下,YAML_VERSION都是0.60
。