File Coverage

blib/lib/Perl/Critic/PolicyParameter/Behavior/Enumeration.pm
Criterion Covered Total %
statement 57 57 100.0
branch 15 16 93.7
condition 12 12 100.0
subroutine 10 10 100.0
pod 2 2 100.0
total 96 97 98.9


line stmt bran cond sub pod time code
1             package Perl::Critic::PolicyParameter::Behavior::Enumeration;
2              
3 40     40   695 use 5.010001;
  40         143  
4 40     40   233 use strict;
  40         100  
  40         760  
5 40     40   188 use warnings;
  40         87  
  40         1156  
6              
7             use Perl::Critic::Exception::Fatal::PolicyDefinition
8 40     40   241 qw( throw_policy_definition );
  40         89  
  40         2173  
9 40     40   272 use Perl::Critic::Utils qw( :characters words_from_string hashify );
  40         93  
  40         2030  
10              
11 40     40   9767 use parent qw{ Perl::Critic::PolicyParameter::Behavior };
  40         106  
  40         242  
12              
13             our $VERSION = '1.150';
14              
15             #-----------------------------------------------------------------------------
16              
17             sub initialize_parameter {
18 738     738 1 1937 my ($self, $parameter, $specification) = @_;
19              
20             my $valid_values = $specification->{enumeration_values}
21 738 100       2483 or throw_policy_definition
22             'No enumeration_values given for '
23             . $parameter->get_name()
24             . $PERIOD;
25 737 100       2513 ref $valid_values eq 'ARRAY'
26             or throw_policy_definition
27             'The value given for enumeration_values for '
28             . $parameter->get_name()
29             . ' is not an array reference.';
30 736 100       1370 scalar @{$valid_values} > 1
  736         2172  
31             or throw_policy_definition
32             'There were not at least two valid values given for'
33             . ' enumeration_values for '
34             . $parameter->get_name()
35             . $PERIOD;
36              
37             # Unfortunately, this has to be a reference, rather than a regular hash,
38             # due to a problem in Devel::Cycle
39             # (http://rt.cpan.org/Ticket/Display.html?id=25360) which causes
40             # t/92_memory_leaks.t to fall over.
41 734         1576 my $value_lookup = { hashify( @{$valid_values} ) };
  734         2544  
42 734         2808 $parameter->_get_behavior_values()->{enumeration_values} = $value_lookup;
43              
44             my $allow_multiple_values =
45 734         1747 $specification->{enumeration_allow_multiple_values};
46              
47 734 100       1990 if ($allow_multiple_values) {
48             $parameter->_set_parser(
49             sub {
50             # Normally bad thing, obscuring a variable in an outer scope
51             # with a variable with the same name is being done here in
52             # order to remain consistent with the parser function interface.
53 457     457   1431 my ($policy, $parameter, $config_string) = @_; ## no critic(Variables::ProhibitReusedNames)
54              
55 457         973 my @potential_values;
56 457   100     2181 my $value_string = $config_string // $parameter->get_default_string();
57              
58 457 100       1376 if ( defined $value_string ) {
59 456         1402 @potential_values = words_from_string($value_string);
60              
61             my @bad_values =
62 456         1259 grep { not exists $value_lookup->{$_} } @potential_values;
  462         1326  
63 456 100       1401 if (@bad_values) {
64             $policy->throw_parameter_value_exception(
65             $parameter->get_name(),
66             $value_string,
67             undef,
68             q{contains invalid values: }
69             . join (q{, }, @bad_values)
70             . q{. Allowed values are: }
71 1         10 . join (q{, }, sort keys %{$value_lookup})
  1         7  
72             . qq{.\n},
73             );
74             }
75             }
76              
77 456         1384 my %actual_values = hashify(@potential_values);
78              
79 456         2229 $policy->__set_parameter_value($parameter, \%actual_values);
80              
81 456         1150 return;
82             }
83 457         3063 );
84             } else {
85             $parameter->_set_parser(
86             sub {
87             # Normally bad thing, obscuring a variable in an outer scope
88             # with a variable with the same name is being done here in
89             # order to remain consistent with the parser function interface.
90 277     277   1124 my ($policy, $parameter, $config_string) = @_; ## no critic(Variables::ProhibitReusedNames)
91              
92 277   100     1367 my $value_string = $config_string // $parameter->get_default_string();
93              
94 277 100 100     2142 if (
      100        
95             defined $value_string
96             and $EMPTY ne $value_string
97             and not defined $value_lookup->{$value_string}
98             ) {
99             $policy->throw_parameter_value_exception(
100             $parameter->get_name(),
101             $value_string,
102             undef,
103             q{is not one of the allowed values: }
104 2         26 . join (q{, }, sort keys %{$value_lookup})
  2         31  
105             . qq{.\n},
106             );
107             }
108              
109 275         1262 $policy->__set_parameter_value($parameter, $value_string);
110              
111 275         649 return;
112             }
113 277         2139 );
114             }
115              
116 734         1963 return;
117             }
118              
119             #-----------------------------------------------------------------------------
120              
121             sub generate_parameter_description {
122 72     72 1 176 my ($self, $parameter) = @_;
123              
124 72         187 my $description = $parameter->_get_description_with_trailing_period();
125 72 50       236 if ( $description ) {
126 72         156 $description .= qq{\n};
127             }
128              
129 72         112 my %values = %{$parameter->_get_behavior_values()->{enumeration_values}};
  72         174  
130             return
131 72         711 $description
132             . 'Valid values: '
133             . join (', ', sort keys %values)
134             . $PERIOD;
135             }
136              
137             #-----------------------------------------------------------------------------
138              
139             1;
140              
141             __END__
142              
143             #-----------------------------------------------------------------------------
144              
145             =pod
146              
147             =for stopwords
148              
149             =head1 NAME
150              
151             Perl::Critic::PolicyParameter::Behavior::Enumeration - Actions appropriate for an enumerated value.
152              
153              
154             =head1 DESCRIPTION
155              
156             Provides a standard set of functionality for an enumerated
157             L<Perl::Critic::PolicyParameter|Perl::Critic::PolicyParameter> so that
158             the developer of a policy does not have to provide it her/himself.
159              
160             NOTE: Do not instantiate this class. Use the singleton instance held
161             onto by
162             L<Perl::Critic::PolicyParameter|Perl::Critic::PolicyParameter>.
163              
164              
165             =head1 INTERFACE SUPPORT
166              
167             This is considered to be a non-public class. Its interface is subject
168             to change without notice.
169              
170              
171             =head1 METHODS
172              
173             =over
174              
175             =item C<initialize_parameter( $parameter, $specification )>
176              
177             Plug in the functionality this behavior provides into the parameter,
178             based upon the configuration provided by the specification.
179              
180             This behavior looks for two configuration items:
181              
182             =over
183              
184             =item enumeration_values
185              
186             Mandatory. The set of valid values for the parameter, as an array
187             reference.
188              
189              
190             =item enumeration_allow_multiple_values
191              
192             Optional, defaults to false. Should the parameter support a single
193             value or accept multiple?
194              
195              
196             =back
197              
198              
199             =item C<generate_parameter_description( $parameter )>
200              
201             Create a description of the parameter, based upon the description on
202             the parameter itself, but enhancing it with information from this
203             behavior.
204              
205             In this specific case, the universe of values is added at the end.
206              
207              
208             =back
209              
210              
211             =head1 AUTHOR
212              
213             Elliot Shank <perl@galumph.com>
214              
215              
216             =head1 COPYRIGHT
217              
218             Copyright (c) 2006-2023 Elliot Shank.
219              
220             This program is free software; you can redistribute it and/or modify
221             it under the same terms as Perl itself. The full text of this license
222             can be found in the LICENSE file included with this module.
223              
224             =cut
225              
226             # Local Variables:
227             # mode: cperl
228             # cperl-indent-level: 4
229             # fill-column: 78
230             # indent-tabs-mode: nil
231             # c-indentation-style: bsd
232             # End:
233             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :