File Coverage

blib/lib/Perl/ToPerl6/TransformerParameter.pm
Criterion Covered Total %
statement 99 131 75.5
branch 11 28 39.2
condition 1 3 33.3
subroutine 26 37 70.2
pod 6 7 85.7
total 143 206 69.4


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