File: list.pm

package info (click to toggle)
libcatmandu-perl 1.2024-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,552 kB
  • sloc: perl: 17,037; makefile: 24; sh: 1
file content (133 lines) | stat: -rw-r--r-- 2,603 bytes parent folder | download
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