File Coverage

blib/lib/Data/Section.pm
Criterion Covered Total %
statement 93 93 100.0
branch 31 38 81.5
condition 6 9 66.6
subroutine 13 13 100.0
pod n/a
total 143 153 93.4


line stmt bran cond sub pod time code
1 2     2   41600 use strict;
  2         4  
  2         68  
2 2     2   12 use warnings;
  2         4  
  2         118  
3             package Data::Section;
4             # ABSTRACT: read multiple hunks of data out of your DATA section
5             $Data::Section::VERSION = '0.200006';
6 2     2   1313 use Encode qw/decode/;
  2         20220  
  2         225  
7 2     2   1595 use MRO::Compat 0.09;
  2         7051  
  2         149  
8             use Sub::Exporter 0.979 -setup => {
9             groups => { setup => \'_mk_reader_group' },
10 11         63267 collectors => { INIT => sub { $_[0] = { into => $_[1]->{into} } } },
11 2     2   1825 };
  2         28463  
  2         35  
12              
13             # =head1 SYNOPSIS
14             #
15             # package Letter::Resignation;
16             # use Data::Section -setup;
17             #
18             # sub quit {
19             # my ($class, $angry, %arg) = @_;
20             #
21             # my $template = $self->section_data(
22             # ($angry ? "angry_" : "professional_") . "letter"
23             # );
24             #
25             # return fill_in($$template, \%arg);
26             # }
27             #
28             # __DATA__
29             # __[ angry_letter ]__
30             # Dear jerks,
31             #
32             # I quit!
33             #
34             # --
35             # {{ $name }}
36             # __[ professional_letter ]__
37             # Dear {{ $boss }},
38             #
39             # I quit, jerks!
40             #
41             #
42             # --
43             # {{ $name }}
44             #
45             # =head1 DESCRIPTION
46             #
47             # Data::Section provides an easy way to access multiple named chunks of
48             # line-oriented data in your module's DATA section. It was written to allow
49             # modules to store their own templates, but probably has other uses.
50             #
51             # =head1 WARNING
52             #
53             # You will need to use C<__DATA__> sections and not C<__END__> sections. Yes, it
54             # matters. Who knew!
55             #
56             # =head1 EXPORTS
57             #
58             # To get the methods exported by Data::Section, you must import like this:
59             #
60             # use Data::Section -setup;
61             #
62             # Optional arguments may be given to Data::Section like this:
63             #
64             # use Data::Section -setup => { ... };
65             #
66             # Valid arguments are:
67             #
68             # encoding - if given, gives the encoding needed to decode bytes in
69             # data sections; default; UTF-8
70             #
71             # the special value "bytes" will leave the bytes in the string
72             # verbatim
73             #
74             # inherit - if true, allow packages to inherit the data of the packages
75             # from which they inherit; default: true
76             #
77             # header_re - if given, changes the regex used to find section headers
78             # in the data section; it should leave the section name in $1
79             #
80             # default_name - if given, allows the first section to has no header and set
81             # its name
82             #
83             # Three methods are exported by Data::Section:
84             #
85             # =head2 section_data
86             #
87             # my $string_ref = $pkg->section_data($name);
88             #
89             # This method returns a reference to a string containing the data from the name
90             # section, either in the invocant's C<DATA> section or in that of one of its
91             # ancestors. (The ancestor must also derive from the class that imported
92             # Data::Section.)
93             #
94             # By default, named sections are delimited by lines that look like this:
95             #
96             # __[ name ]__
97             #
98             # You can use as many underscores as you want, and the space around the name is
99             # optional. This pattern can be configured with the C<header_re> option (see
100             # above). If present, a single leading C<\> is removed, so that sections can
101             # encode lines that look like section delimiters.
102             #
103             # When a line containing only C<__END__> is reached, all processing of sections
104             # ends.
105             #
106             # =head2 section_data_names
107             #
108             # my @names = $pkg->section_data_names;
109             #
110             # This returns a list of all the names that will be recognized by the
111             # C<section_data> method.
112             #
113             # =head2 merged_section_data
114             #
115             # my $data = $pkg->merged_section_data;
116             #
117             # This method returns a hashref containing all the data extracted from the
118             # package data for all the classes from which the invocant inherits -- as long as
119             # those classes also inherit from the package into which Data::Section was
120             # imported.
121             #
122             # In other words, given this inheritance tree:
123             #
124             # A
125             # \
126             # B C
127             # \ /
128             # D
129             #
130             # ...if Data::Section was imported by A, then when D's C<merged_section_data> is
131             # invoked, C's data section will not be considered. (This prevents the read
132             # position of C's data handle from being altered unexpectedly.)
133             #
134             # The keys in the returned hashref are the section names, and the values are
135             # B<references to> the strings extracted from the data sections.
136             #
137             # =head2 merged_section_data_names
138             #
139             # my @names = $pkg->merged_section_data_names;
140             #
141             # This returns a list of all the names that will be recognized by the
142             # C<merged_section_data> method.
143             #
144             # =head2 local_section_data
145             #
146             # my $data = $pkg->local_section_data;
147             #
148             # This method returns a hashref containing all the data extracted from the
149             # package on which the method was invoked. If called on an object, it will
150             # operate on the package into which the object was blessed.
151             #
152             # This method needs to be used carefully, because it's weird. It returns only
153             # the data for the package on which it was invoked. If the package on which it
154             # was invoked has no data sections, it returns an empty hashref.
155             #
156             # =head2 local_section_data_names
157             #
158             # my @names = $pkg->local_section_data_names;
159             #
160             # This returns a list of all the names that will be recognized by the
161             # C<local_section_data> method.
162             #
163             # =cut
164              
165             sub _mk_reader_group {
166 11     11   850 my ($mixin, $name, $arg, $col) = @_;
167 11         29 my $base = $col->{INIT}{into};
168              
169 11         57 my $default_header_re = qr/
170             \A # start
171             _+\[ # __[
172             \s* # any whitespace
173             ([^\]]+?) # this is the actual name of the section
174             \s* # any whitespace
175             \]_+ # ]__
176             [\x0d\x0a]{1,2} # possible cariage return for windows files
177             \z # end
178             /x;
179              
180 11   66     77 my $header_re = $arg->{header_re} || $default_header_re;
181 11 100       50 $arg->{inherit} = 1 unless exists $arg->{inherit};
182              
183 11 100       37 my $default_encoding = defined $arg->{encoding} ? $arg->{encoding} : 'UTF-8';
184              
185 11         25 my %export;
186 11         24 my %stash = ();
187              
188             $export{local_section_data} = sub {
189 47     47   10148 my ($self) = @_;
190              
191 47 50       93 my $pkg = ref $self ? ref $self : $self;
192              
193 47 100       262 return $stash{ $pkg } if $stash{ $pkg };
194              
195 15         37 my $template = $stash{ $pkg } = { };
196              
197 2     2   1362 my $dh = do { no strict 'refs'; \*{"$pkg\::DATA"} }; ## no critic Strict
  2         5  
  2         1943  
  15         21  
  15         18  
  15         49  
198 15 100       52 return $stash{ $pkg } unless defined fileno *$dh;
199 14         136 binmode( $dh, ":raw :bytes" );
200              
201 14         19 my ($current, $current_line);
202 14 100       55 if ($arg->{default_name}) {
203 1         2 $current = $arg->{default_name};
204 1         4 $template->{ $current } = \(my $blank = q{});
205             }
206 14         217 LINE: while (my $line = <$dh>) {
207 57 100       284 if ($line =~ $header_re) {
208 27         52 $current = $1;
209 27         30 $current_line = 0;
210 27         58 $template->{ $current } = \(my $blank = q{});
211 27         98 next LINE;
212             }
213              
214 30 100       60 last LINE if $line =~ /^__END__/;
215 29 100 66     85 next LINE if !defined $current and $line =~ /^\s*$/;
216              
217 26 50       41 Carp::confess("bogus data section: text outside of named section")
218             unless defined $current;
219              
220 26         28 $current_line++;
221 26 50       53 unless ($default_encoding eq 'bytes') {
222 26 50       30 my $decoded_line = eval { decode($default_encoding, $line, Encode::FB_CROAK) }
  26         139  
223             or warn "Invalid character encoding in $current, line $current_line\n";
224 26 50       1766 $line = $decoded_line if defined $decoded_line;
225             }
226 26         39 $line =~ s/\A\\//;
227              
228 26         27 ${$template->{$current}} .= $line;
  26         168  
229             }
230              
231 14         78 return $stash{ $pkg };
232 11         87 };
233              
234             $export{local_section_data_names} = sub {
235 6     6   11 my ($self) = @_;
236 6         11 my $method = $export{local_section_data};
237 6         6 return keys %{ $self->$method };
  6         9  
238 11         49 };
239              
240             $export{merged_section_data} =
241             !$arg->{inherit} ? $export{local_section_data} : sub {
242              
243 12     12   15 my ($self) = @_;
244 12 50       27 my $pkg = ref $self ? ref $self : $self;
245              
246 12         18 my $lsd = $export{local_section_data};
247              
248 12         16 my %merged;
249 12         13 for my $class (@{ mro::get_linear_isa($pkg) }) {
  12         76  
250             # in case of c3 + non-$base item showing up
251 25 100       134 next unless $class->isa($base);
252 20         37 my $sec_data = $class->$lsd;
253              
254             # checking for truth is okay, since things must be undef or a ref
255             # -- rjbs, 2008-06-06
256 20   66     265 $merged{ $_ } ||= $sec_data->{$_} for keys %$sec_data;
257             }
258              
259 12         65 return \%merged;
260 11 100       67 };
261              
262             $export{merged_section_data_names} = sub {
263 6     6   9 my ($self) = @_;
264 6         11 my $method = $export{merged_section_data};
265 6         7 return keys %{ $self->$method };
  6         8  
266 11         49 };
267              
268             $export{section_data} = sub {
269 11     11   3416 my ($self, $name) = @_;
270 11 50       30 my $pkg = ref $self ? ref $self : $self;
271              
272 11 100       31 my $prefix = $arg->{inherit} ? 'merged' : 'local';
273 11         17 my $method = "$prefix\_section_data";
274              
275 11         39 my $data = $self->$method;
276              
277 11         58 return $data->{ $name };
278 11         296 };
279              
280             $export{section_data_names} = sub {
281 4     4   8 my ($self) = @_;
282              
283 4 100       12 my $prefix = $arg->{inherit} ? 'merged' : 'local';
284 4         10 my $method = "$prefix\_section_data_names";
285 4         18 return $self->$method;
286 11         46 };
287              
288 11         45 return \%export;
289             }
290              
291             # =head1 TIPS AND TRICKS
292             #
293             # =head2 MooseX::Declare and namespace::autoclean
294             #
295             # The L<namespace::autoclean|namespace::autoclean> library automatically cleans
296             # foreign routines from a class, including those imported by Data::Section.
297             #
298             # L<MooseX::Declare|MooseX::Declare> does the same thing, and can also cause your
299             # C<__DATA__> section to appear outside your class's package.
300             #
301             # These are easy to address. The
302             # L<Sub::Exporter::ForMethods|Sub::Exporter::ForMethods> library provides an
303             # installer that will cause installed methods to appear to come from the class
304             # and avoid autocleaning. Using an explicit C<package> statement will keep the
305             # data section in the correct package.
306             #
307             # package Foo;
308             #
309             # use MooseX::Declare;
310             # class Foo {
311             #
312             # # Utility to tell Sub::Exporter modules to export methods.
313             # use Sub::Exporter::ForMethods qw( method_installer );
314             #
315             # # method_installer returns a sub.
316             # use Data::Section { installer => method_installer }, -setup;
317             #
318             # method my_method {
319             # my $content_ref = $self->section_data('SectionA');
320             #
321             # print $$content_ref;
322             # }
323             # }
324             #
325             # __DATA__
326             # __[ SectionA ]__
327             # Hello, world.
328             #
329             # =head1 SEE ALSO
330             #
331             # =begin :list
332             #
333             # * L<article for RJBS Advent 2009|http://advent.rjbs.manxome.org/2009/2009-12-09.html>
334             #
335             # * L<Inline::Files|Inline::Files> does something that is at first look similar,
336             # but it works with source filters, and contains the warning:
337             #
338             # It is possible that this module may overwrite the source code in files that
339             # use it. To protect yourself against this possibility, you are strongly
340             # advised to use the -backup option described in "Safety first".
341             #
342             # Enough said.
343             #
344             # =end :list
345             #
346             # =cut
347              
348             1;
349              
350             __END__
351              
352             =pod
353              
354             =encoding UTF-8
355              
356             =head1 NAME
357              
358             Data::Section - read multiple hunks of data out of your DATA section
359              
360             =head1 VERSION
361              
362             version 0.200006
363              
364             =head1 SYNOPSIS
365              
366             package Letter::Resignation;
367             use Data::Section -setup;
368              
369             sub quit {
370             my ($class, $angry, %arg) = @_;
371              
372             my $template = $self->section_data(
373             ($angry ? "angry_" : "professional_") . "letter"
374             );
375              
376             return fill_in($$template, \%arg);
377             }
378              
379             __DATA__
380             __[ angry_letter ]__
381             Dear jerks,
382              
383             I quit!
384              
385             --
386             {{ $name }}
387             __[ professional_letter ]__
388             Dear {{ $boss }},
389              
390             I quit, jerks!
391              
392              
393             --
394             {{ $name }}
395              
396             =head1 DESCRIPTION
397              
398             Data::Section provides an easy way to access multiple named chunks of
399             line-oriented data in your module's DATA section. It was written to allow
400             modules to store their own templates, but probably has other uses.
401              
402             =head1 WARNING
403              
404             You will need to use C<__DATA__> sections and not C<__END__> sections. Yes, it
405             matters. Who knew!
406              
407             =head1 EXPORTS
408              
409             To get the methods exported by Data::Section, you must import like this:
410              
411             use Data::Section -setup;
412              
413             Optional arguments may be given to Data::Section like this:
414              
415             use Data::Section -setup => { ... };
416              
417             Valid arguments are:
418              
419             encoding - if given, gives the encoding needed to decode bytes in
420             data sections; default; UTF-8
421              
422             the special value "bytes" will leave the bytes in the string
423             verbatim
424              
425             inherit - if true, allow packages to inherit the data of the packages
426             from which they inherit; default: true
427              
428             header_re - if given, changes the regex used to find section headers
429             in the data section; it should leave the section name in $1
430              
431             default_name - if given, allows the first section to has no header and set
432             its name
433              
434             Three methods are exported by Data::Section:
435              
436             =head2 section_data
437              
438             my $string_ref = $pkg->section_data($name);
439              
440             This method returns a reference to a string containing the data from the name
441             section, either in the invocant's C<DATA> section or in that of one of its
442             ancestors. (The ancestor must also derive from the class that imported
443             Data::Section.)
444              
445             By default, named sections are delimited by lines that look like this:
446              
447             __[ name ]__
448              
449             You can use as many underscores as you want, and the space around the name is
450             optional. This pattern can be configured with the C<header_re> option (see
451             above). If present, a single leading C<\> is removed, so that sections can
452             encode lines that look like section delimiters.
453              
454             When a line containing only C<__END__> is reached, all processing of sections
455             ends.
456              
457             =head2 section_data_names
458              
459             my @names = $pkg->section_data_names;
460              
461             This returns a list of all the names that will be recognized by the
462             C<section_data> method.
463              
464             =head2 merged_section_data
465              
466             my $data = $pkg->merged_section_data;
467              
468             This method returns a hashref containing all the data extracted from the
469             package data for all the classes from which the invocant inherits -- as long as
470             those classes also inherit from the package into which Data::Section was
471             imported.
472              
473             In other words, given this inheritance tree:
474              
475             A
476             \
477             B C
478             \ /
479             D
480              
481             ...if Data::Section was imported by A, then when D's C<merged_section_data> is
482             invoked, C's data section will not be considered. (This prevents the read
483             position of C's data handle from being altered unexpectedly.)
484              
485             The keys in the returned hashref are the section names, and the values are
486             B<references to> the strings extracted from the data sections.
487              
488             =head2 merged_section_data_names
489              
490             my @names = $pkg->merged_section_data_names;
491              
492             This returns a list of all the names that will be recognized by the
493             C<merged_section_data> method.
494              
495             =head2 local_section_data
496              
497             my $data = $pkg->local_section_data;
498              
499             This method returns a hashref containing all the data extracted from the
500             package on which the method was invoked. If called on an object, it will
501             operate on the package into which the object was blessed.
502              
503             This method needs to be used carefully, because it's weird. It returns only
504             the data for the package on which it was invoked. If the package on which it
505             was invoked has no data sections, it returns an empty hashref.
506              
507             =head2 local_section_data_names
508              
509             my @names = $pkg->local_section_data_names;
510              
511             This returns a list of all the names that will be recognized by the
512             C<local_section_data> method.
513              
514             =head1 TIPS AND TRICKS
515              
516             =head2 MooseX::Declare and namespace::autoclean
517              
518             The L<namespace::autoclean|namespace::autoclean> library automatically cleans
519             foreign routines from a class, including those imported by Data::Section.
520              
521             L<MooseX::Declare|MooseX::Declare> does the same thing, and can also cause your
522             C<__DATA__> section to appear outside your class's package.
523              
524             These are easy to address. The
525             L<Sub::Exporter::ForMethods|Sub::Exporter::ForMethods> library provides an
526             installer that will cause installed methods to appear to come from the class
527             and avoid autocleaning. Using an explicit C<package> statement will keep the
528             data section in the correct package.
529              
530             package Foo;
531              
532             use MooseX::Declare;
533             class Foo {
534              
535             # Utility to tell Sub::Exporter modules to export methods.
536             use Sub::Exporter::ForMethods qw( method_installer );
537              
538             # method_installer returns a sub.
539             use Data::Section { installer => method_installer }, -setup;
540              
541             method my_method {
542             my $content_ref = $self->section_data('SectionA');
543              
544             print $$content_ref;
545             }
546             }
547              
548             __DATA__
549             __[ SectionA ]__
550             Hello, world.
551              
552             =head1 SEE ALSO
553              
554             =over 4
555              
556             =item *
557              
558             L<article for RJBS Advent 2009|http://advent.rjbs.manxome.org/2009/2009-12-09.html>
559              
560             =item *
561              
562             L<Inline::Files|Inline::Files> does something that is at first look similar,
563              
564             but it works with source filters, and contains the warning:
565              
566             It is possible that this module may overwrite the source code in files that
567             use it. To protect yourself against this possibility, you are strongly
568             advised to use the -backup option described in "Safety first".
569              
570             Enough said.
571              
572             =back
573              
574             =head1 AUTHOR
575              
576             Ricardo SIGNES <rjbs@cpan.org>
577              
578             =head1 COPYRIGHT AND LICENSE
579              
580             This software is copyright (c) 2008 by Ricardo SIGNES.
581              
582             This is free software; you can redistribute it and/or modify it under
583             the same terms as the Perl 5 programming language system itself.
584              
585             =cut