This file is indexed.

/usr/share/perl5/MooX/BuildArgsHooks.pm is in libmoox-buildargs-perl 0.04-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
package MooX::BuildArgsHooks;
$MooX::BuildArgsHooks::VERSION = '0.04';
=head1 NAME

MooX::BuildArgsHooks - Structured BUILDARGS.

=head1 SYNOPSIS

    package Foo;
    use Moo;
    with 'MooX::BuildArgsHooks';
    
    has bar => (is=>'ro');
    
    around NORMALIZE_BUILDARGS => sub{
        my ($orig, $class, @args) = @_;
        @args = $class->$orig( @args );
        return( bar=>$args[0] ) if @args==1 and ref($args[0]) ne 'HASH';
        return @args;
    };
    
    around TRANSFORM_BUILDARGS => sub{
        my ($orig, $class, $args) = @_;
        $args = $class->$orig( $args );
        $args->{bar} = ($args->{bar}||0) + 10;
        return $args;
    };
    
    around FINALIZE_BUILDARGS => sub{
        my ($orig, $class, $args) = @_;
        $args = $class->$orig( $args );
        $args->{bar}++;
        return $args;
    };
    
    print Foo->new( 3 )->bar(); # 14

=head1 DESCRIPTION

This module installs some hooks directly into L<Moo> which allow
for more fine-grained access to the phases of C<BUILDARGS>.  The
reason this is important is because if you have various roles and
classes modifying BUILDARGS you will often end up with weird
behaviors depending on what order the various BUILDARGS wrappers
are applied in.  By breaking up argument processing into three
steps (normalize, transform, and finalize) these conflicts are
much less likely to arise.

To further avoid these kinds of issues, and this applies to any
system where you would C<around> methods from a consuming role or
super class not just BUILDARGS, it is recommended that you implement
your extensions via methods.  This way if something inherits from your
role or class they can treat your method as a hook.  For example:

    around TRANSFORM_BUILDARGS => sub{
        my ($class, $orig, $args) = @_;
        $args = $class->$orig( $args );
        return $class->TRANSFORM_FOO_BUILDARGS( $args );
    };
    
    sub TRANSFORM_FOO_BUILDARGS {
        my ($class, $args) = @_;
        $args->{bar} = ($args->{bar}||0) + 10;
        return $args;
    }

Then if some other code wishes to inject code before or after
the C<Foo> class transforming BUILDARGS they can do so at very
specific points.

=cut

use Class::Method::Modifiers qw( install_modifier );
use Moo::Object qw();

use Moo::Role;
use strictures 2;
use namespace::clean;

BEGIN {
    package MooX::BuildArgsHooks::Test;
$MooX::BuildArgsHooks::Test::VERSION = '0.04';
    use Moo;
    around BUILDARGS => sub{
        my $orig = shift;
        my $class = shift;
        return $class->$orig( @_ );
    };
    has normalize => ( is=>'rw' );
    has transform => ( is=>'rw' );
    has finalize  => ( is=>'rw' );
    sub NORMALIZE_BUILDARGS { $_[0]->normalize(1); shift; @_ }
    sub TRANSFORM_BUILDARGS { $_[0]->transform(1); $_[1] }
    sub FINALIZE_BUILDARGS  { $_[0]->finalize(1); $_[1] }
}

# When installing these modifiers we're going to be super defensive
# and not overwrite anything that may have already declared these
# methods or even provides this functionality already.  This should
# hopefully make this module relatively future proof.
BEGIN {
    my $moo = 'Moo::Object';

    install_modifier(
        $moo, 'fresh',
        'NORMALIZE_BUILDARGS' => sub{ shift; @_ },
    ) unless $moo->can('NORMALIZE_BUILDARGS');

    install_modifier(
        $moo, 'fresh',
        'TRANSFORM_BUILDARGS' => sub{ $_[1] },
    ) unless $moo->can('TRANSFORM_BUILDARGS');

    install_modifier(
        $moo, 'fresh',
        'FINALIZE_BUILDARGS' => sub{ $_[1] },
    ) unless $moo->can('FINALIZE_BUILDARGS');

    my $test = MooX::BuildArgsHooks::Test->new();
    my $does_normalize = $test->normalize();
    my $does_transform = $test->transform();
    my $does_finalize  = $test->finalize();
    $test = undef;

    unless ($does_normalize and $does_transform and $does_finalize) {
        install_modifier(
            $moo, 'around',
            'BUILDARGS' => sub{
                my ($orig, $class, @args) = @_;

                @args = $class->NORMALIZE_BUILDARGS( @args ) unless $does_normalize;

                my $args = $class->$orig( @args );

                $args = $class->TRANSFORM_BUILDARGS( { %$args } ) unless $does_transform;

                $args = $class->FINALIZE_BUILDARGS( { %$args } ) unless $does_finalize;

                return $args;
            },
        );
    }
}

# Must declare a custom no-op BUILDARGS otherwise
# Method::Generate::Constructor gets in the way.
# Alternatively we could modify its inlined BUILDARGS
# to include our logic, but that's making things even
# more brittle.
around BUILDARGS => sub{
    my $orig = shift;
    my $class = shift;
    return $class->$orig( @_ );
};

1;
__END__

=head1 HOOKS

A hook in the context of this module is just a method that has
been declared in the inheritance hierarchy and is made available
for consuming roles and classes to apply method modifiers to.

=head2 NORMALIZE_BUILDARGS

    around NORMALIZE_BUILDARGS => sub{
        my ($orig, $class, @args) = @_;

        # Make sure you let other normalizations happen.
        @args = $class->$orig( @args );

        # Do your normalization logic.
        ...

        return @args;
    };

Used to do some basic normalization of arguments from some
custom format to a format acceptable to Moo (a hash or a
hashref).

This is useful, for example, when you want to support single
arguments.  For example:

    around NORMALIZE_BUILDARGS => sub{
        my ($orig, $class, @args) = @_;

        # If only one argument is passed in assume that it is
        # the value for the foo attribute.
        if (@args==1 and ref($args[0]) ne 'HASH') {
            @args = { foo => $args[0] };
        }

        @args = $class->$orig( @args );

        return @args;
    };

Or you could just use L<MooX::SingleArg>.

=head2 TRANSFORM_BUILDARGS

    around TRANSFORM_BUILDARGS => sub{
        my ($orig, $class, $args) = @_;

        # Make sure you let any other transformations happen.
        $args = $class->$orig( $args );

        # Do your transformations.
        ...

        return $args;
    };

This hook is the workhorse where much of the C<BUILDARGS> work
typically happens.  By the time this hook is called the arguments
will always be in hashref form, not a list, and a hashref must be
returned.

=head2 FINALIZE_BUILDARGS

    around FINAL_BUILDARGS => sub{
        my ($orig, $class, $args) = @_;

        # Let any other hooks have a turn.
        $args = $class->$orig( $args );

        # Do your finalization logic.
        ...

        return $args;
    };

This hook works just like L</TRANFORM_BUILDARGS> except that it happens
after it and is meant to be used by hooks that are the last step in the
argument building process and need access to the arguments after most
all other steps have completed.

=head1 SEE ALSO

=over

=item *

L<MooX::BuildArgs>

=item *

L<MooX::MethodProxyArgs>

=item *

L<MooX::Rebuild>

=item *

L<MooX::SingleArg>

=back

=head1 AUTHOR

Aran Clary Deltac <bluefeetE<64>gmail.com>

=head1 CONTRIBUTORS

=over

=item *

Peter Pentchev <roamE<64>ringlet.net>

=back

=head1 LICENSE

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.