2013-02-18 2 views

답변

5

사용해보십시오 :

나는 노력하고

a = A.new(*JSON[json].values) 
a.class # => A < #<Class:0x00000102955828> 

문제는 values가를 반환한다는 것입니다 배열하지만 배열의 개별 요소가 필요합니다. *을 사용하면 배열을 해당 구성 요소로 "다시 표시"하여 new에 값을 전달할 때 구조체를 행복하게 만듭니다.


편집 :

This will fail if the ordering of the JSON and the Struct do not match!

이 값의 순서를 강제로.

a = A.new(*JSON[json].values_at('a', 'b')) 
{ 
    :a => 1, 
    :b => 2 
} 
a.class # => A < #<Class:0x00000102955828> 

JSON은 Ruby와 마찬가지로 해시 삽입 순서를 유지하므로 Ruby에서 렌더링 및 파싱 된 JSON이 정확합니다. 순서를 유지하지 않는 것으로 렌더링 된 JSON은 문제 일 수 있지만 values_at은 문제를 수정합니다.

JSON은 심볼을 문자열로 변환하므로 values_at에 전달 된 키는 기호가 아니라 문자열이어야합니다.

+0

이 실패합니다 작동합니다! – akuhn

+0

JSON은 루비 해시와 마찬가지로 순서를 유지합니다. 따라서 Ruby에서 JSON을 생성 한 다음 Ruby에서받은 경우 순서는 손상되지 않아야합니다. 하지만 추가 할 간단한 해결 방법이 있습니다. –

+1

예, 그렇습니다. 하지만 JSON도 웹에서 올 수 있습니다. 그런 다음 버그를 찾기가 정말 어렵습니다. – akuhn

1

연산자 splat 연산자를 사용하여 배열 값을 새 함수의 인수로 전달할 수 있습니다.

a = A.new(*{a:1,b:2}.values) 
3

는 미리 정의 된 구조체 수없는 경우, 이것이 JSON과 구조체의 순서가 일치하지 않는 경우

a = Struct.new(*json.keys).new(*json.values) 
+0

'Struct.new (* ({ 'a => 1} .keys))'원인 :'NameError : 식별자가 일정해야합니다'. 멤버 이름으로 문자열을 전달할 수없는 것 같습니다. 'json.keys.map (& : to_sym)'을 사용할 수는 있지만 루비가 2.2보다 작 으면 기호가 GC하지 않기 때문에 DOS가 발생할 수 있습니다. – Kelvin

관련 문제