2011-11-04 1 views
2

, 가끔YAML :: JSON을 지원하지 않습니다 작은 :: XS :: 부울

YAML::Tiny does not support JSON::XS::Boolean 

내가 이해 오류 이 경우 (YAML::Tiny은 부울을 지원하지 않습니다. JSON은 다른 스칼라와 명확히 구분됩니다). JSON::XS::Boolean 개체를 일반 01의 개체로 변환하는 빠른 해킹이 있습니다. 빠른 덤프 - 투 - 화면 목적?

답변

3

YAML::Tiny은 개체를 지원하지 않습니다. 불행하게도, 모든 객체를 문자열로 변환하는 옵션조차 가지고 있지 않다. JSON::XS::Boolean을 처리 할 것이다.

당신은하지만, 재귀 기능을 비교적 쉽게 그렇게 할 수 있습니다

use strict; 
use warnings; 
use 5.010; # for say 

use JSON::XS qw(decode_json); 
use Scalar::Util qw(blessed reftype); 
use YAML::Tiny qw(Dump); 

my $hash = decode_json('{ "foo": { "bar": true }, "baz": false }'); 

# Stringify all objects in $hash: 
sub stringify_objects { 
    for my $val (@_) { 
    next unless my $ref = reftype $val; 
    if (blessed $val) { $val = "$val" } 
    elsif ($ref eq 'ARRAY') { stringify_objects(@$val) } 
    elsif ($ref eq 'HASH') { stringify_objects(values %$val) } 
    } 
} 

stringify_objects($hash); 

say Dump $hash; 

이 기능은 스칼라 참조를 처리 귀찮게하지 않는, JSON은을 생산하지 않습니다 때문이다. 또한 객체가 실제로 문자열을 오버로드했는지 여부도 확인하지 않습니다.

Data::Rmap은 아무리 여러 번 나타나도 특정 개체를 한 번만 방문하므로 잘 작동하지 않습니다. JSON::XS::Boolean 개체는 싱글 톤이므로 첫 번째 메시지는 true이고 첫 번째 메시지는 false입니다. 그것은 그 해결하는 것이 가능하지만, 그 seen 해시 생성하는 방법 키를 결정하기 위해 소스 코드에 탐구가 필요합니다

use Data::Rmap qw(rmap_ref); 
use Scalar::Util qw(blessed refaddr); 

# Stringify all objects in $hash: 
rmap_ref { if (blessed $_) { delete $_[0]->seen->{refaddr $_}; 
          $_ = "$_" } } $hash; 

나는 재귀 함수가 명확하다고 생각, 그것은 Data::Rmap의 변화에 ​​취약하지 않습니다.

+0

답변으로 관련 질문을 추가 했으므로 코드를 게시 할 수 있습니다. –

+0

흠 .. 값 중 하나 (예 :'true ')가 두 번 이상 나타나면 실제로 작동하지 않습니다. 어떤 이유로 첫 번째 부울 만 문자열로 변환됩니다. 왜 그런가? –

+0

@JuanAntonio, 단지 하나의'true' 객체와 하나의'false' 객체가 있기 때문입니다. JSON :: XS는 여러 번 참조합니다. 내 업데이트 답변을 참조하십시오. – cjm

관련 문제