1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
package Catmandu::Fix::Bind::list;
use Catmandu::Sane;
our $VERSION = '1.2024';
use Moo;
use Clone ();
use Catmandu::Util;
use namespace::clean;
use Catmandu::Fix::Has;
with 'Catmandu::Fix::Bind', 'Catmandu::Fix::Bind::Group';
has path => (fix_opt => 1);
has var => (fix_opt => 1);
has root => (is => 'rw');
sub zero {
my ($self) = @_;
[];
}
sub unit {
my ($self, $data) = @_;
$self->root($data);
defined $self->path ? Catmandu::Util::data_at($self->path, $data) : $data;
}
sub bind {
my ($self, $mvar, $code) = @_;
my $root = $self->root;
my $var = $self->var;
if (Catmandu::Util::is_hash_ref($mvar)) {
# Ignore all specialized processing when not an array
$mvar = $code->($mvar);
return $mvar;
}
elsif (Catmandu::Util::is_array_ref($mvar)) {
for my $item (@$mvar) {
if (defined $var) {
$root->{$var} = $item;
$root = $code->($root);
delete $root->{$var};
}
else {
$item = $code->($item);
}
}
return $mvar;
}
else {
return $self->zero;
}
}
1;
__END__
=pod
=head1 NAME
Catmandu::Fix::Bind::list - a binder that computes Fix-es for every element in a list
=head1 SYNOPSIS
# Create an array:
# demo:
# - red
# - green
# - yellow
# Add a foo field to every item in the demo list, by default all
# fixes will be in context of the iterated path. If the context
# is a list, then '.' will be the path of the temporary context
# variable
do list(path:demo)
if all_equal(.,green)
upcase(.)
end
end
# This will result:
# demo:
# - red
# - GREEN
# - yellow
# Loop over the list but store the values in a temporary 'c' variable
# Use this c variable to copy the list to the root 'xyz' path
do list(path:demo,var:c)
copy_field(c,xyz.$append)
end
# This will result:
# demo:
# - red
# - GREEN
# - yellow
# xyz:
# - red
# - GREEN
# - yellow
=head1 DESCRIPTION
The list binder will iterate over all the elements in a list and fixes the
values in context of that list.
=head1 CONFIGURATION
=head2 path
The path to a list in the data.
=head2 var
The loop variable to be iterated over. When used, a magic temporary field will
be available in the root of the record containing the iterated data.
=head1 SEE ALSO
L<Catmandu::Fix::Bind>
=cut
|