0.foo.bar = 0foobar
0.foo.baz = 0foobaz
1.foo = 1foo
equates to:
[
{
foo =>
{
bar => '0foobar',
baz => '0foobaz'
}
},
{
foo => '1foo'
}
]
####
>.foo.bar = 0foobar
<.foo.baz = 0foobaz
>.foo = 1foo
####
use strict;
use warnings;
use Data::Diver qw#DiveVal DiveError#;
use Data::Dumper qw#Dumper#;
$/ = qq#\r\n#;
my $state = { };
my $ref = undef;
while ( my $line = )
{
next if ( $line =~ qr#^(\#|\s*$)# ); # ignore line if comment or blank.
chomp $line; # remove newline.
my ( $selector, $value ) = split qr#\s*=\s*#, $line; # (selector)=(value). todo: unless escaped.
next if ( not defined $selector ); # ignore line if no selector.
my @selector = split qr#\.#, $selector; # (one).(two).(three)... todo: unless escaped.
$ref //= ( $selector[0] =~ qr#^([><]|\d+)$# ) ? [ ] : { } ;
_dive( $ref, \@selector, $value );
}
print Dumper $state, $ref;
sub _dive
{
my ( $ref, $selector, $value ) = @_;
return if ( not defined $ref or not defined $selector or not scalar @$selector ); # return if no ref or no selectees.
my @selector_b = qw##;
for my $selectee ( @$selector )
{
if ( $selectee =~ qr#^([><])$# ) # if incognito selectee. todo: unless escaped.
{
my $selector_b = join q#.#, @selector_b;
if ( $1 eq q#># ) # incognito selectee is of increment type.
{
if ( defined $state->{$selector_b} ) # we have seen this state before.
{
push @selector_b, $state->{$selector_b} += 1; # push current index + 1.
}
else
{
push @selector_b, $state->{$selector_b} = 0; # push 0 (first) index.
}
}
elsif ( $1 eq q#<# ) # incognito selectee is of maintain type.
{
push @selector_b, $state->{$selector_b} //= 0; # push current index or 0 (first) index.
}
}
else # else non inconito selectee.
{
push @selector_b, $selectee; # push selectee.
}
}
DiveVal( $ref, @selector_b ) = $value;
my ( $error ) = DiveError( );
$error and warn $error;
return 1;
}
__DATA__
>.name = john
<.location = uk
<.interests.> = programming
<.interests.> = cycling
>.name = laura
<.location =
<.interests.> = knitting
<.interests.> = tennis
<.interests.> = dancing
>.name
<.location = canada
<.interests.>.> = dogs
<.interests.<.> = horses
<.interests.> = cars
# test.error = blah
####
$VAR1 = {
'2.interests' => 1,
'' => 2,
'2.interests.0' => 1,
'0.interests' => 1,
'1.interests' => 2
};
$VAR2 = [
{
'interests' => [
'programming',
'cycling'
],
'location' => 'uk',
'name' => 'john'
},
{
'interests' => [
'knitting',
'tennis',
'dancing'
],
'location' => '',
'name' => 'laura'
},
{
'interests' => [
[
'dogs',
'horses'
],
'cars'
],
'location' => 'canada',
'name' => undef
}
];