Mojolicious-Plugin-FeedReader
view release on metacpan or search on metacpan
t/samples/perlmonks.html view on Meta::CPAN
{
foo => '1foo'
}
]
</tt></div><div class='embed-code-dl'><a href="?abspart=1;displaytype=displaycode;node_id=1105074;part=1">[download]</a></div></pre>
<p>The data is parsed by splitting the key into its individual components then running them through Data::Diver. The problem is I sometimes need to add data into the middle of the dataset and as a result have to increment index components within keys...
<pre class="code"><div class='codeblock'><tt class='codetext'>>.foo.bar = 0foobar
<.foo.baz = 0foobaz
>.foo = 1foo
</tt></div><div class='embed-code-dl'><a href="?abspart=1;displaytype=displaycode;node_id=1105074;part=2">[download]</a></div></pre>
<p>Where '>' means "next index // 0" and '<' means "last index // 0", within scope of the dimension. I wrote the following demo:</p>
<pre class="code"><div class='codeblock'><tt class='codetext'>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 = <DATA> )
{
next if ( $line =~ qr#^(\#|\s*$)# ); # ignore line if comment or b<span class="line-breaker">
<font color="red">+</font></span>lank.
chomp $line; # remove newline.
my ( $selector, $value ) = split qr#\s*=\s*#, $line; # (selector)=<span class="line-breaker">
<font color="red">+</font></span>(value). todo: unless escaped.
next if ( not defined $selector ); # ignore line if no selector.
my @selector = split qr#\.#, $selector; # (one).(two).(three)... t<span class="line-breaker">
<font color="red">+</font></span>odo: 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 scala<span class="line-breaker">
<font color="red">+</font></span>r @$selector ); # return if no ref or no selectees.
my @selector_b = qw##;
for my $selectee ( @$selector )
{
if ( $selectee =~ qr#^([><])$# ) # if incognito selectee. todo<span class="line-breaker">
<font color="red">+</font></span>: unless escaped.
{
my $selector_b = join q#.#, @selector_b;
if ( $1 eq q#># ) # incognito selectee is of increment typ<span class="line-breaker">
<font color="red">+</font></span>e.
{
if ( defined $state->{$selector_b} ) # we have seen th<span class="line-breaker">
<font color="red">+</font></span>is state before.
{
push @selector_b, $state->{$selector_b} += 1; # pu<span class="line-breaker">
<font color="red">+</font></span>sh current index + 1.
}
else
{
push @selector_b, $state->{$selector_b} = 0; # pus<span class="line-breaker">
<font color="red">+</font></span>h 0 (first) index.
}
}
elsif ( $1 eq q#<# ) # incognito selectee is of maintain t<span class="line-breaker">
<font color="red">+</font></span>ype.
{
push @selector_b, $state->{$selector_b} //= 0; # push <span class="line-breaker">
<font color="red">+</font></span>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
</tt></div><div class='embed-code-dl'><a href="?abspart=1;displaytype=displaycode;node_id=1105074;part=3">[download]</a></div></pre>
<p>Output:</p>
<pre class="code"><div class='codeblock'><tt class='codetext'>$VAR1 = {
'2.interests' => 1,
'' => 2,
'2.interests.0' => 1,
'0.interests' => 1,
'1.interests' => 2
};
$VAR2 = [
{
'interests' => [
'programming',
'cycling'
],
'location' => 'uk',
'name' => 'john'
},
( run in 0.426 second using v1.01-cache-2.11-cpan-e93a5daba3e )