073eac656b30ba23212f9c308cc11212477c4c29
[gitmo/Perl-Critic-Dynamic-Moose.git] / lib / Perl / Critic / Policy / DynamicMoose / ProhibitPublicBuilders.pm
1 package Perl::Critic::Policy::DynamicMoose::ProhibitPublicBuilders;
2 use Moose;
3 extends 'Perl::Critic::Policy::DynamicMoose';
4
5 use Perl::Critic::Utils ':severities';
6 use Perl::Critic::Utils::Moose 'meta_type';
7
8 Readonly::Scalar my $EXPL => q{Prefix builder method names with an underscore};
9 sub default_severity { $SEVERITY_MEDIUM }
10
11 augment applies_to_metaclass => sub { 'Moose::Meta::Role' };
12
13 sub violates_metaclass {
14     my $self = shift;
15     my $meta = shift;
16
17     my $classname = $meta->name;
18
19     my @violations;
20
21     my $attributes = $meta->get_attribute_map;
22     for my $name (keys %$attributes) {
23         my $attribute = $attributes->{$name};
24         my $builder;
25
26         if (blessed($attribute)) {
27             next if !$attribute->has_builder;
28             $builder = $attribute->builder;
29         }
30         else {
31             # Roles suck :(
32             next if !defined($attribute->{builder});
33             $builder = $attribute->{builder};
34         }
35
36         if ($builder !~ /^_/) {
37             my $type = meta_type($meta);
38             my $desc = "Builder method '$builder' of attribute '$attribute' of $type '$classname' is public";
39             push @violations, $self->violation($desc, $EXPL);
40         }
41     }
42
43     return @violations;
44 }
45
46 no Moose;
47
48 1;
49
50 __END__
51
52 =head1 NAME
53
54 Perl::Critic::Policy::DynamicMoose::ProhibitPublicBuilders
55
56 =head1 DESCRIPTION
57
58 An attribute's L<Moose/builder> method is used to provide a default value
59 for that attribute. Such methods are rarely intended for external use, and
60 should not be considered part of that class's public API. Thus we recommend
61 that your attribute builder methods' names are prefixed with an underscore
62 to mark them private.
63
64 =head1 WARNING
65
66 B<VERY IMPORTANT:> Most L<Perl::Critic> Policies (including all the ones that
67 ship with Perl::Critic> use pure static analysis -- they never compile nor
68 execute any of the code that they analyze.  However, this policy is very
69 different.  It actually attempts to compile your code and then compares the
70 subroutines mentioned in your code to those found in the symbol table.
71 Therefore you should B<not> use this Policy on any code that you do not trust,
72 or may have undesirable side-effects at compile-time (such as connecting to the
73 network or mutating files).
74
75 For this Policy to work, all the modules included in your code must be
76 installed locally, and must compile without error.
77
78 =head1 AUTHOR
79
80 Shawn M Moore, C<sartak@bestpractical.com>
81
82 =cut
83