use strict;
use warnings;
use Tie::IxHash;
use Data::Dumper;
use Data::Rmap qw(:types rmap_to);
sub ixhash_to_yamlxs
{
my $item = \+shift;
my $get_yaml_struct = sub {
my $raw = shift;
my $ix = tied(%$raw);
return $raw unless defined $ix and $ix->isa('Tie::IxHash');
return [ map { { $_ => $raw->{$_} } } $ix->Keys ];
};
rmap_to { $_ = $get_yaml_struct->($_) } HASH, $item;
return $item;
}
sub yamlxs_to_ixhash
{
my $item = shift;
my $make_ixhash_from_array = sub {
my $raw = shift;
tie my(%hash), 'Tie::IxHash';
eval {
no warnings;
for (@$raw) {
return $raw if scalar keys $_ ne 1;
my ($key) = keys $_;
$hash{$key} = $_->{$key};
}
};
return $raw if $@;
return \%hash;
};
rmap_to { $_ = $make_ixhash_from_array->($_) } ARRAY, \$item;
return $item;
}
tie my(%embed), 'Tie::IxHash', (j => 5, k => 6, l => 7);
tie my(%hash), 'Tie::IxHash', (a => 1, c => { z => 26 }, b => 2, d => [ 'j', 'k', 'l'], e => \%embed);
my $out = ixhash_to_yamlxs \%hash;
print Dumper $out;
my $in = yamlxs_to_ixhash $out;
print Dumper $in;
####
# IxHash converted for output by YAML::XS
# Notice the embeded IxHash was handled
# and also an embeded native hash (key 'c')
# that is not converted to ordered structure
\[
{ 'a' => 1 },
{ 'c' => { 'z' => 26 } },
{ 'b' => 2 },
{ 'd' => [ 'j', 'k', 'l' ] },
{ 'e' => [ { 'j' => 5 },
{ 'k' => 6 },
{ 'l' => 7 }
]
}
];
####
# ordered Tie::IxHash recovered from YAML::XS format
\{
'a' => 1,
'c' => { 'z' => 26 },
'b' => 2,
'd' => [ 'j', 'k', 'l' ],
'e' => {
'j' => 5,
'k' => 6,
'l' => 7
}
};