File Coverage

blib/lib/Perl/ToPerl6/TransformerParameter.pm
Criterion Covered Total %
statement 101 131 77.1
branch 12 28 42.8
condition 1 3 33.3
subroutine 27 37 72.9
pod 6 7 85.7
total 147 206 71.3


line stmt bran cond sub pod time code
1             package Perl::ToPerl6::TransformerParameter;
2              
3 23     23   475 use 5.006001;
  23         62  
4 23     23   104 use strict;
  23         31  
  23         939  
5 23     23   94 use warnings;
  23         37  
  23         637  
6 23     23   90 use Readonly;
  23         30  
  23         1066  
7              
8 23     23   105 use Exporter 'import';
  23         30  
  23         1094  
9              
10             Readonly::Array our @EXPORT_OK => qw{ $NO_DESCRIPTION_AVAILABLE };
11              
12 23     23   98 use String::Format qw{ stringf };
  23         30  
  23         1017  
13              
14             use Perl::ToPerl6::Exception::Fatal::TransformerDefinition
15 23     23   102 qw{ throw_transformer_definition };
  23         32  
  23         1053  
16 23     23   9135 use Perl::ToPerl6::TransformerParameter::Behavior;
  23         48  
  23         718  
17 23     23   9609 use Perl::ToPerl6::TransformerParameter::Behavior::Boolean;
  23         46  
  23         577  
18 23     23   10399 use Perl::ToPerl6::TransformerParameter::Behavior::Enumeration;
  23         70  
  23         637  
19 23     23   10060 use Perl::ToPerl6::TransformerParameter::Behavior::Integer;
  23         45  
  23         647  
20 23     23   9690 use Perl::ToPerl6::TransformerParameter::Behavior::String;
  23         42  
  23         610  
21 23     23   9789 use Perl::ToPerl6::TransformerParameter::Behavior::StringList;
  23         68  
  23         823  
22              
23 23     23   125 use Perl::ToPerl6::Utils qw{ :characters &interpolate };
  23         32  
  23         1316  
24 23     23   4064 use Perl::ToPerl6::Utils::DataConversion qw{ &defined_or_empty };
  23         33  
  23         23019  
25              
26             our $VERSION = '0.03';
27              
28             Readonly::Scalar our $NO_DESCRIPTION_AVAILABLE => 'No description available.';
29              
30             #-----------------------------------------------------------------------------
31              
32             # Grrr... one of the OO limitations of Perl: you can't put references to
33             # subclases in a superclass (well, not nicely). This map and method belong
34             # in Behavior.pm.
35             Readonly::Hash my %BEHAVIORS =>
36             (
37             'boolean' => Perl::ToPerl6::TransformerParameter::Behavior::Boolean->new(),
38             'enumeration' => Perl::ToPerl6::TransformerParameter::Behavior::Enumeration->new(),
39             'integer' => Perl::ToPerl6::TransformerParameter::Behavior::Integer->new(),
40             'string' => Perl::ToPerl6::TransformerParameter::Behavior::String->new(),
41             'string list' => Perl::ToPerl6::TransformerParameter::Behavior::StringList->new(),
42             );
43              
44             sub _get_behavior_for_name {
45 21     21   27 my $behavior_name = shift;
46              
47 21 50       124 my $behavior = $BEHAVIORS{$behavior_name}
48             or throw_transformer_definition( qq{There's no "$behavior_name" behavior.} );
49              
50 21         275 return $behavior;
51             }
52              
53             #-----------------------------------------------------------------------------
54              
55             sub new {
56 21     21 0 12228 my ($class, $specification) = @_;
57 21         45 my $self = bless {}, $class;
58              
59 21 50       57 defined $specification
60             or throw_transformer_definition(
61             'Attempt to create a ', __PACKAGE__, ' without a specification.' );
62              
63 21         21 my $behavior_specification;
64              
65 21         39 my $specification_type = ref $specification;
66 21 50       45 if ( not $specification_type ) {
67 0         0 $self->{_name} = $specification;
68              
69 0         0 $behavior_specification = {};
70             } else {
71 21 50       68 $specification_type eq 'HASH'
72             or throw_transformer_definition(
73             'Attempt to create a ',
74             __PACKAGE__,
75             " with a $specification_type as a specification.",
76             );
77              
78             defined $specification->{name}
79 21 50       47 or throw_transformer_definition(
80             'Attempt to create a ', __PACKAGE__, ' without a name.' );
81 21         71 $self->{_name} = $specification->{name};
82              
83 21         29 $behavior_specification = $specification;
84             }
85              
86 21         47 $self->_initialize_from_behavior($behavior_specification);
87 17         41 $self->_finish_standard_initialization($behavior_specification);
88              
89 17         44 return $self;
90             }
91              
92             # See if the specification includes a Behavior name, and if so, let the
93             # Behavior with that name plug in its implementations of parser, etc.
94             sub _initialize_from_behavior {
95 21     21   28 my ($self, $specification) = @_;
96              
97 21         31 my $behavior_name = $specification->{behavior};
98 21         25 my $behavior;
99 21 50       34 if ($behavior_name) {
100 21         41 $behavior = _get_behavior_for_name($behavior_name);
101             } else {
102 0         0 $behavior = _get_behavior_for_name('string');
103             }
104              
105 21         40 $self->{_behavior} = $behavior;
106 21         30 $self->{_behavior_values} = {};
107              
108 21         81 $behavior->initialize_parameter($self, $specification);
109              
110 17         23 return;
111             }
112              
113             # Grab the rest of the values out of the specification, including overrides
114             # of what the Behavior specified.
115             sub _finish_standard_initialization {
116 17     17   23 my ($self, $specification) = @_;
117              
118             my $description =
119 17   33     54 $specification->{description} || $NO_DESCRIPTION_AVAILABLE;
120 17         39 $self->_set_description($description);
121 17         52 $self->_set_default_string($specification->{default_string});
122              
123 17         50 $self->_set_parser($specification->{parser});
124              
125 17         27 return;
126             }
127              
128             #-----------------------------------------------------------------------------
129              
130             sub get_name {
131 116     116 1 114 my $self = shift;
132              
133 116         322 return $self->{_name};
134             }
135              
136             #-----------------------------------------------------------------------------
137              
138             sub get_description {
139 0     0 1 0 my $self = shift;
140              
141 0         0 return $self->{_description};
142             }
143              
144             sub _set_description {
145 17     17   24 my ($self, $new_value) = @_;
146              
147 17 50       35 return if not defined $new_value;
148 17         28 $self->{_description} = $new_value;
149              
150 17         19 return;
151             }
152              
153             sub _get_description_with_trailing_period {
154 0     0   0 my $self = shift;
155              
156 0         0 my $description = $self->get_description();
157 0 0       0 if ($description) {
158 0 0       0 if ( $PERIOD ne substr $description, ( length $description ) - 1 ) {
159 0         0 $description .= $PERIOD;
160             }
161             } else {
162 0         0 $description = $EMPTY;
163             }
164              
165 0         0 return $description;
166             }
167              
168             #-----------------------------------------------------------------------------
169              
170             sub get_default_string {
171 56     56 1 55 my $self = shift;
172              
173 56         108 return $self->{_default_string};
174             }
175              
176             sub _set_default_string {
177 17     17   29 my ($self, $new_value) = @_;
178              
179 17 100       34 return if not defined $new_value;
180 11         22 $self->{_default_string} = $new_value;
181              
182 11         41 return;
183             }
184              
185             #-----------------------------------------------------------------------------
186              
187             sub _get_behavior {
188 0     0   0 my $self = shift;
189              
190 0         0 return $self->{_behavior};
191             }
192              
193             sub _get_behavior_values {
194 17     17   22 my $self = shift;
195              
196 17         38 return $self->{_behavior_values};
197             }
198              
199             #-----------------------------------------------------------------------------
200              
201             sub _get_parser {
202 56     56   53 my $self = shift;
203              
204 56         77 return $self->{_parser};
205             }
206              
207             sub _set_parser {
208 34     34   53 my ($self, $new_value) = @_;
209              
210 34 100       64 return if not defined $new_value;
211 17         30 $self->{_parser} = $new_value;
212              
213 17         38 return;
214             }
215              
216             #-----------------------------------------------------------------------------
217              
218             sub parse_and_validate_config_value {
219 56     56 1 536 my ($self, $transformer, $config) = @_;
220              
221 56         118 my $config_string = $config->{$self->get_name()};
222              
223 56         108 my $parser = $self->_get_parser();
224 56 50       119 if ($parser) {
225 56         140 $parser->($transformer, $self, $config_string);
226             }
227              
228 49         94 return;
229             }
230              
231             #-----------------------------------------------------------------------------
232              
233             sub generate_full_description {
234 0     0 1   my ($self) = @_;
235              
236 0           return $self->_get_behavior()->generate_parameter_description($self);
237             }
238              
239             #-----------------------------------------------------------------------------
240              
241             sub _generate_full_description {
242 0     0     my ($self, $prefix) = @_;
243              
244 0           my $description = $self->generate_full_description();
245              
246 0 0         if (not $description) {
247 0           return $EMPTY;
248             }
249              
250 0 0         if ($prefix) {
251 0           $description =~ s/ ^ /$prefix/xmsg;
252             }
253              
254 0           return $description;
255             }
256              
257             #-----------------------------------------------------------------------------
258              
259             sub to_formatted_string {
260 0     0 1   my ($self, $format) = @_;
261              
262             my %specification = (
263 0     0     n => sub { $self->get_name() },
264 0     0     d => sub { defined_or_empty( $self->get_description() ) },
265 0     0     D => sub { defined_or_empty( $self->get_default_string() ) },
266 0     0     f => sub { $self->_generate_full_description(@_) },
267 0           );
268              
269 0           return stringf( interpolate($format), %specification );
270             }
271              
272             #-----------------------------------------------------------------------------
273              
274             1;
275              
276             __END__
277              
278             #-----------------------------------------------------------------------------
279              
280             =pod
281              
282             =for stopwords parsable
283              
284             =head1 NAME
285              
286             Perl::ToPerl6::TransformerParameter - Metadata about a parameter for a Transformer.
287              
288              
289             =head1 DESCRIPTION
290              
291             A provider of validation and parsing of parameter values and metadata
292             about the parameter.
293              
294              
295             =head1 INTERFACE SUPPORT
296              
297             This is considered to be a public class. Any changes to its interface
298             will go through a deprecation cycle.
299              
300              
301             =head1 METHODS
302              
303             =over
304              
305             =item C<get_name()>
306              
307             Return the name of the parameter. This is the key that will be looked
308             for in the F<.perlmogrifyrc>.
309              
310              
311             =item C<get_description()>
312              
313             Return an explanation of the significance of the parameter, as
314             provided by the developer of the transformer.
315              
316              
317             =item C<get_default_string()>
318              
319             Return a representation of the default value of this parameter as it
320             would appear if it was specified in a F<.perlmogrifyrc> file.
321              
322              
323             =item C<parse_and_validate_config_value( $parser, $config )>
324              
325             Extract the configuration value for this parameter from the overall
326             configuration and initialize the transformer based upon it.
327              
328              
329             =item C<generate_full_description()>
330              
331             Produce a more complete explanation of the significance of this
332             parameter than the value returned by C<get_description()>.
333              
334             If no description can be derived, returns the empty string.
335              
336             Note that the result may contain multiple lines.
337              
338              
339             =item C<to_formatted_string( $format )>
340              
341             Generate a string representation of this parameter, based upon the
342             format.
343              
344             The format is a combination of literal and escape characters similar
345             to the way C<sprintf> works. If you want to know the specific
346             formatting capabilities, look at L<String::Format|String::Format>.
347             Valid escape characters are:
348              
349             =over
350              
351             =item C<%n>
352              
353             The name of the parameter.
354              
355             =item C<%d>
356              
357             The description, as supplied by the programmer.
358              
359             =item C<%D>
360              
361             The default value, in a parsable form.
362              
363             =item C<%f>
364              
365             The full description, which is an extension of the value returned by
366             C<%d>. Takes a parameter of a prefix for the beginning of each line.
367              
368              
369             =back
370              
371              
372             =back
373              
374              
375             =head1 SEE ALSO
376              
377             L<Perl::ToPerl6::DEVELOPER/"MAKING YOUR POLICY CONFIGURABLE">
378              
379              
380             =head1 AUTHOR
381              
382             Elliot Shank <perl@galumph.com>
383              
384             =head1 COPYRIGHT
385              
386             Copyright (c) 2006-2011 Elliot Shank.
387              
388             This program is free software; you can redistribute it and/or modify
389             it under the same terms as Perl itself. The full text of this license
390             can be found in the LICENSE file included with this module.
391              
392             =cut
393              
394             # Local Variables:
395             # mode: cperl
396             # cperl-indent-level: 4
397             # fill-column: 78
398             # indent-tabs-mode: nil
399             # c-indentation-style: bsd
400             # End:
401             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :