Data-Overlay
view release on metacpan or search on metacpan
lib/Data/Overlay.pm view on Meta::CPAN
...;
return $result;
},
args => [ ... ], # optional argument list
}
=cut
$action_map{run} = sub {
my ($old_ds, $overlay) = @_;
return $overlay->{code}->($old_ds, @{ $overlay->{args} || [] });
};
=item foreach
Apply one overlay to all elements of an array or values of a hash
(or just a scalar). Often useful with =run if the overlay is
a function of the original value.
=cut
# XXX each with (k,v) or [i,...]
$action_map{foreach} = sub {
my ($old_ds, $overlay, $conf) = @_;
if (_isreftype(ARRAY => $old_ds)) {
return [
map { overlay($_, $overlay, $conf) } @$old_ds
];
} elsif (_isreftype(HASH => $old_ds)) {
return {
map {
$_ => overlay($old_ds->{$_}, $overlay, $conf)
} keys %$old_ds
};
} else {
return overlay($old_ds, $overlay, $conf);
}
};
=item seq
Apply in sequence an array of overlays.
=cut
$action_map{seq} = sub {
my ($old_ds, $overlay, $conf) = @_;
# XXX reftype $overlay
my $ds = $old_ds;
for my $ol (@$overlay) {
$ds = overlay($ds, $ol, $conf);
}
return $ds;
};
=back
=cut
for my $action (keys %action_map) {
# debuggable names for callbacks (not the used perl names)
subname "$action-overlay", $action_map{$action};
# XXX
warn "$action not in \@action_order"
if ! grep { $action eq $_ } @action_order;
}
sub _wrap_debug {
my ($action_name, $inner_sub) = @_;
my $s = subname "$action_name-debug", sub {
my ($old_ds, $overlay, $conf) = @_;
my $debug = max($conf->{debug},
( ref($conf->{debug_actions})
&& $conf->{debug_actions}{$action_name} ));
if ($debug) {
warn "Calling $action_name $inner_sub\n";
warn " with ", _dt($overlay), "\n" if $debug >= 1;
warn " conf ", _dt({map { "$_" } %$conf}), "\n" if $debug >= 2;
cluck " CALL STACK" if $debug >= 3;
}
my $result = $inner_sub->($old_ds, $overlay, $conf);
if ($debug) {
warn " Back from $action_name\n";
warn " got ", _dt($result), "\n" if $debug >= 2;
}
return $result;
};
warn "Wrapped $inner_sub with $s";
return $s;
}
sub _dt {
require Data::Dumper;
my $dumper = Data::Dumper->new( map [$_], @_ );
$dumper->Indent(0)->Terse(1);
$dumper->Sortkeys(1) if $dumper->can("Sortkeys");
return $dumper->Dump;
}
__PACKAGE__; # true return
__END__
exists
delete
and/if/ifthen replace if $ds is true
sprintf prepend_str append_str interpolate $_
splice grep map sort
+/-/*/++/--/x/%/**/./<</>>
| & ^ ~ masks boolean logic
conditionals? comparison?
deref?
invert apply inverted
swap overlay and ds roles
splitting one ds val into multiple new_ds?
( run in 0.537 second using v1.01-cache-2.11-cpan-39bf76dae61 )