2012-07-09 4 views
1

난 문맥에서 YAML을 사용하여 루비 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" 

개의 출력 충실 별개이므로, I는 순방향있어 내 레일 애플리케이션 내부를 부호화.

그러나 레일스 컨텍스트 내에서 루비는 정수 범위를 올바르게 직렬화하는 방법을 잊어 버렸습니다!

# ./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! 

레일에 루비와 루비 모두 YAML 라이브러리의 동일한 버전을 사용하는 것 같습니다. 내가 잘못 이해하지 않는다면, 내 버전의 루비는 여러 코더 엔진을 전환하는 것을 지원하지 않는다.

  1. 이러한 차이의 원인은 무엇입니까 :

    나는 몇 가지 질문이?
  2. 이 문제는 의 최신 버전에서 발생합니다. ruby ​​/레일?
  3. 호환되는 방법으로 어떻게 문제를 해결할 수 있습니까?

감사합니다.

+0

2 가지 경우에 YAML :: ENGINE.yamler의 가치는 무엇입니까? –

+0

'NameError : 초기화되지 않은 상수 YAML :: ENGINE' 두 경우 모두, <1.9 버전의 루비 때문인 것 같습니다. – ofavre

답변

0

범위는 정수 또는 문자열과 같은 YAML 기본 유형이 아닌 Ruby 내부입니다. 범위를 그대로 인코딩하는 대신 시작 지점과 끝 지점을 사용하고 수신 측에서 범위를 재구성하십시오.

나는 같은 것을 사용

[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 

문자의

직렬화 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" 

[5] (pry) main: 0> RUBY_VERSION 
=> "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" 
[4] (pry) main: 0> RUBY_VERSION 
=> "1.9.2" 

그리고는 해결 방법은 범위 시작/끝 유형을 유지 :

두 경우 모두 YAML_VERSION은 0.60입니다.

+0

다양한 종류의 객체를 직렬화하고 있지만 범위가 있으면 최상위 객체입니다. 그래서이 의미에서 할 수있는 유일한 일은 Range를 탐지하고 YAML을 에뮬레이트하는 커스텀 코드를 사용하는 것입니다. 그리고 다른 타입들에 대해서도 여전히 평범한 YAML을 사용합니다 ... 나는 100 % 만족하지 않습니다. 해킹)하지만 트릭을 수행 할 수 있습니다. – ofavre

+0

Btw 나는 너에게 똑같은 문제가 있음을 알았다. 레일 콘솔에서 치기를 사용 했습니까? 어떤 버전의 루비 레일? 그리고 yaml 당신이 사용하고 있습니까? – ofavre

+0

범위는 1.9+로 직렬화 될 때 "유형"을 유지합니다. 추가 된 정보를보십시오. –

관련 문제