File Coverage

blib/lib/Config/General/Match.pm
Criterion Covered Total %
statement 98 102 96.0
branch 39 48 81.2
condition 16 25 64.0
subroutine 11 11 100.0
pod 3 3 100.0
total 167 189 88.3


line stmt bran cond sub pod time code
1              
2             package Config::General::Match;
3              
4 15     15   385539 use warnings;
  15         39  
  15         475  
5 15     15   79 use strict;
  15         31  
  15         502  
6              
7 15     15   91 use Carp;
  15         223  
  15         1673  
8              
9 15     15   17972 use Config::General;
  15         604457  
  15         1140  
10 15     15   15599 use Hash::Merge qw();
  15         53368  
  15         26513  
11              
12             our @ISA = qw(Config::General);
13              
14             =head1 NAME
15              
16             Config::General::Match - Add C<< >> and C<< >> style matching to Config::General
17              
18             =head1 VERSION
19              
20             Version 0.05
21              
22             =cut
23              
24             our $VERSION = '0.05';
25              
26             =head1 NOTE
27              
28             This module is obsolete and has now been superceded by
29             L.
30              
31             =head1 SYNOPSIS
32              
33             use Config::General::Match;
34              
35             my $config_text = '
36              
37            
38             title = "User Area"
39            
40              
41            
42             image_file = 1
43            
44              
45             ';
46              
47              
48             my $conf = Config::General::Match->new(
49             -String => $config_text,
50             -MatchSections => [
51             {
52             -Name => 'Location',
53             -MatchType => 'path',
54             },
55             {
56             -Name => 'LocationMatch',
57             -MatchType => 'regex',
58             },
59             ],
60             );
61              
62             my %config = $conf->getall_matching('/users/~mary/index.html');
63             use Data::Dumper;
64             print Dumper(\%config);
65             $VAR1 = {
66             'title' => 'User Area',
67             'image_file' => undef,
68             };
69              
70             my %config = $conf->getall_matching('/users/~biff/images/flaming_logo.gif');
71             print Dumper(\%config);
72             $VAR1 = {
73             'title' => 'User Area',
74             'image_file' => 1,
75             };
76              
77              
78             =head1 DESCRIPTION
79              
80             =head2 Introduction
81              
82             This module extends C by providing support for
83             configuration sections that match only for a particular file or path or
84             URL.
85              
86             Typically you would use this to support the Apache-style conditional
87             blocks, for instance:
88              
89            
90             # ... some configuration ...
91            
92              
93            
94             # ... some configuration ...
95            
96              
97            
98             # ... some configuration ...
99            
100              
101             To read the configuration use C<< $conf->getall_matching >> instead of
102             C<< $conf->getall >>:
103              
104             my $conf = Config::General::Match->new(...);
105             my %config = $conf->getall_matching('/users/joe/index.html');
106             my %other_config = $conf->getall_matching('/images/banner.jpg');
107              
108             =head2 Matching things other than paths
109              
110             The Match feature is general enough that you can use it to match other
111             things besides paths and URLs. For instance you could specify a
112             C<-PathSeparator> of C<::> and use the feature to match against Perl
113             modules:
114              
115             my $config_text = "
116              
117             is_core_module 0
118            
119             is_core_module 1
120             author Nathan Torkington
121            
122              
123            
124             author Richard Jone
125            
126              
127             ";
128              
129             my $conf = Config::General::Match->new(
130             -String => $config_text,
131             -MatchSections => [
132             {
133             -Name => 'Module',
134             -PathSeparator => '::',
135             -MatchType => 'path',
136             },
137             ],
138             );
139              
140             my %config = $conf->getall_matching('Net::FTP');
141             use Data::Dumper;
142             print Dumper(\%config);
143             $VAR1 = {
144             'is_core_module' => 1,
145             'author' => 'Nathan Torkington',
146             };
147              
148             =head2 Merging
149              
150             =head3 Merging with the implied 'Default' section
151              
152             Config values that appear outside of any block act like defaults.
153             Values in matching sections are merged with the default values. For
154             instance:
155              
156             private_area = 0
157             client_area = 0
158              
159            
160             private_area = 1
161            
162              
163            
164             client_area = 1
165            
166              
167             # Admin Area URL
168             my %config = $conf->getall_matching('/admin/index.html');
169             use Data::Dumper;
170             print Dumper(\%config);
171             $VAR1 = {
172             'private_area' => 1,
173             'client_area' => 0,
174             };
175              
176             # Client Area URL
177             my %config = $conf->getall_matching('/clients/index.html');
178             print Dumper(\%config);
179             $VAR1 = {
180             'private_area' => 0,
181             'client_area' => 1,
182             };
183              
184             # Neither Client nor Admin
185             my %config = $conf->getall_matching('/public/index.html');
186             print Dumper(\%config);
187             $VAR1 = {
188             'private_area' => 0,
189             'client_area' => 0,
190             };
191              
192             =head3 Multiple Level Merging
193              
194             Sections and subsections are merged along with single values. For instance:
195              
196             private_area = 0
197             client_area = 0
198            
199             title = "The Widget Emporium"
200             logo = logo.gif
201             advanced_ui = 0
202            
203              
204            
205             private_area = 1
206            
207             title = "The Widget Emporium - Admin Area"
208             logo = admin_logo.gif
209             advanced_ui = 1
210            
211            
212              
213            
214             client_area = 1
215            
216             title = "The Widget Emporium - Wholesalers"
217             logo = client_logo.gif
218            
219            
220              
221             # Admin Area URL
222             my %config = $conf->getall_matching('/admin/index.html');
223             use Data::Dumper;
224             print Dumper(\%config);
225             $VAR1 = {
226             'page_settings' => {
227             'advanced_ui' => '1',
228             'title' => 'The Widget Emporium - Admin Area',
229             'logo' => 'admin_logo.gif'
230             },
231             'private_area' => '1',
232             'client_area' => '0'
233             };
234             # Client Area URL
235             my %config = $conf->getall_matching('/clients/index.html');
236             print Dumper(\%config);
237             $VAR1 = {
238             'page_settings' => {
239             'advanced_ui' => '0',
240             'title' => 'The Widget Emporium - Wholesalers',
241             'logo' => 'client_logo.gif'
242             },
243             'client_area' => '1',
244             'private_area' => '0'
245             };
246              
247             # Neither Client nor Admin
248             my %config = $conf->getall_matching('/public/index.html');
249             print Dumper(\%config);
250             $VAR1 = {
251              
252             'page_settings' => {
253             'advanced_ui' => '0',
254             'title' => 'The Widget Emporium',
255             'logo' => 'logo.gif'
256             },
257             'client_area' => '0',
258             'private_area' => '0'
259              
260             };
261              
262              
263             =head3 Merging Multiple Matching Sections
264              
265             Often more than one section will match the target string. When this
266             happens, the matching sections are merged together using the
267             C module. Typically this means that sections that are
268             merged later override the values set in earlier sections. (But you can
269             change this behaviour. See L below.)
270              
271             The order of merging matters. The sections are merged first according
272             to each section's C<-MergePriority> value (lowest values are merged
273             first), and second by the length of the substring that matched (shortest
274             matches are merged first). If you don't specify C<-MergePriority> for
275             any section, they all default to a priority of C<0> which means all
276             sections are treated equally and matches are prioritized based soley on
277             the length of the matching strings.
278              
279             The order of sections in the config file is ignored.
280              
281             For instance, if your config file looks like this:
282              
283            
284             # section 1
285            
286              
287            
288             # section 2
289            
290              
291            
292             # section 3
293            
294              
295            
296             # section 4
297            
298              
299             ...and you construct your $conf object like this:
300              
301             my $conf = Config::General::Match->new(
302             -MatchSections => [
303             { -Name => 'Directory', -MatchType => 'path' -MergePriority => 1 },
304             { -Name => 'Dir', -MatchType => 'path' -MergePriority => 1 },
305             { -Name => 'Path', -MatchType => 'path' -MergePriority => 2 },
306             ],
307             );
308              
309             ...then the target string '/foo/bar/baz/bam/boom' would match all sections
310             the order of 1, 3, 4, 2.
311              
312              
313              
314             =head1 CONSTRUCTOR
315              
316             =head2 new(...)
317              
318             Creates and returns a new C object.
319              
320             my $conf = Config::General::Match->new(
321             -MatchSections => [
322             { -Name => 'Directory', -MatchType => 'path' },
323             ],
324             -ConfigFile => 'somefile.conf',
325             );
326              
327             The arguments to C are the same as you would provide to
328             C, with the addition of C<-MatchSections>. (But see
329             see the C section for limitations on compatibility with
330             C.)
331              
332             The C<-MatchSections> parameter takes a list of specification hashrefs.
333             Each specification has the following fields:
334              
335             =over 4
336              
337             =item B<-Name>
338              
339             The name of the section. For a name of 'Location', the section would look like:
340              
341            
342            
343              
344             This parameter is affected by the C option
345             C<-LowerCaseNames>. If C<-LowerCaseNames> is true, then the following
346             would all be valid 'Location' sections.
347              
348            
349            
350              
351            
352            
353              
354            
355            
356              
357             =item B<-MatchType>
358              
359             Specifies the method by which the section strings should match the
360             target string.
361              
362             The valid types of matches are 'exact', 'substring', 'regex', 'path',
363             and 'hierarchical'
364              
365             =over 4
366              
367             =item exact
368              
369             The config section string matches only if it is equal to the target
370             string. For instance:
371              
372             # somefile.conf
373            
374             ...
375            
376             ...
377              
378              
379             my $conf = Config::General::Match->new(
380             -MatchSections => [
381             {
382             -Name => 'Site',
383             -MatchType => 'exact',
384             },
385             ],
386             -ConfigFile => 'somefile.conf',
387             );
388              
389             In this case, only the string C would match the section.
390              
391             =item substring
392              
393             The config section string is tested to see if it is a substring of the
394             target string. For instance:
395              
396             # somefile.conf
397            
398             ...
399            
400              
401             ...
402              
403              
404             my $conf = Config::General::Match->new(
405             -MatchSections => [
406             {
407             -Name => 'LocationMatch',
408             -MatchType => 'substring',
409             },
410             ],
411             -ConfigFile => 'somefile.conf',
412             );
413              
414             In this case, the following target strings would all match:
415              
416             /foo
417             big_foo.html
418             /hotfood
419              
420             Do not quote the match string; it will not work if you do so.
421              
422             =item regex
423              
424             The config section string is treated as a regular expression against
425             which the target string is matched. For instance:
426              
427             # somefile.conf
428            
429             Image = 1
430            
431              
432             ...
433              
434             my $conf = Config::General::Match->new(
435             -MatchSections => [
436             {
437             -Name => 'LocationMatch',
438             -MatchType => 'regex',
439             },
440             ],
441             -ConfigFile => 'somefile.conf',
442             );
443              
444             my %config = $conf->getall_matching('banner.jpg');
445              
446             The regex can contain any valid Perl regular expression. So to match
447             case-insensitively you can use the C<(?i:)> syntax:
448              
449            
450             UserDir = 1
451            
452              
453             Also note that the regex is not tied to the beginning of the target
454             string by default. So for regexes involving paths you will probably
455             want to do so explicitly:
456              
457            
458             UserDir = 1
459            
460              
461             Do not quote a regex; it will not work if you do so.
462              
463             =item path
464              
465             This method is useful for matching paths, URLs, Perl Modules and other
466             hierarchical strings.
467              
468             The config section string is tested against the the target string
469             according to the following rules:
470              
471             =over 4
472              
473             =item *
474              
475             The section string is a substring of the target string
476              
477             =item *
478              
479             The section string starts at the first character of the target string
480              
481             =item *
482              
483             In the target string, the section string is followed immediately by
484             C<-PathSeparator> or the end-of-string.
485              
486             =back
487              
488             For instance:
489              
490             # somefile.conf
491            
492            
493              
494             ...
495              
496             my $conf = Config::General::Match->new(
497             -MatchSections => [
498             {
499             -Name => 'LocationMatch',
500             -MatchType => 'path',
501             },
502             ],
503             -ConfigFile => 'somefile.conf',
504             );
505              
506             In this case, the following target strings would all match:
507              
508             /foo
509             /foo/
510             /foo/bar
511             /foo/bar.txt
512              
513             But the following strings would B match:
514              
515             /foo.txt
516             /food
517             /food/bar.txt
518             foo.txt
519              
520             Do not quote the path; it will not work if you do so.
521              
522             =item hierarchical
523              
524             A synonym for 'path'.
525              
526             =back
527              
528             =item B<-PathSeparator>
529              
530             The path separator when matching hierarchical strings (paths, URLs,
531             Module names, etc.). It defaults to '/'.
532              
533             This parameter is ignored unless the C<-MatchType> is 'path' or
534             'hierarchical'.
535              
536             =item B<-SectionType>
537              
538             Allows you to only process certain sections for certain types of
539             strings. For instance, you could match some sections against a given
540             filesystem path and some sections against a Perl module name, using the
541             same config file.
542              
543             # somefile.conf
544             # section 1
545            
546             Perl_Module = 1
547             Core_Module = 1
548             Installed_Module = 0
549            
550              
551             # section 2
552            
553             Core_Module = 0
554            
555              
556             # section 3
557             # Note the whitespace at the end of the section name, to prevent File from
558             # being parsed as a stand-alone block by Config::General
559            
560             Installed_Module = 1
561            
562              
563             # section 4
564            
565             FTP_Module = 1
566            
567              
568             my $conf = Config::General::Match->new(
569             -MatchSections => [
570             {
571             -Name => 'FileMatch',
572             -MatchType => 'regex',
573             -SectionType => 'file',
574             },
575             {
576             -Name => 'File',
577             -MatchType => 'path',
578             -SectionType => 'file',
579             },
580             {
581             -Name => 'Module',
582             -MatchType => 'path',
583             -Separator => '::',
584             -SectionType => 'module',
585             },
586             ],
587             -ConfigFile => 'somefile.conf',
588              
589             # need to turn off C-style comment parsing because of the
590             # */ in the name of section 3
591             -CComments => 0,
592             );
593              
594             my %config = $conf->getall_matching(
595             file => '/usr/lib/perl5/site_perl/5.6.1/NET/FTP/Common.pm',
596             module => 'NET::FTP::Common',
597             );
598              
599             This tests C against
600             sections 1, 2 and 3 (and merging them in the order of shortest to
601             longest match, i.e. 1, 3, 2).
602              
603             Then it tests 'NET::FTP::Common' against section 4 (which also matches).
604             The resulting configuration is:
605              
606             use Data::Dumper;
607             print Dumper(\%config);
608             $VAR1 = {
609             'Perl_Module' => 1,
610             'Core_Module' => 0,
611             'FTP_Module' => 1,
612             'Installed_Module' => 1,
613             };
614              
615             Another example:
616              
617             my %config = $conf->getall_matching(
618             file => '/var/www/cgi-lib/FTP/FTPServer.pm',
619             module => 'NET::FTPServer',
620             );
621              
622             This tests C against sections 1, 2
623             and 3, and matches only against section 1. Then it matches
624             'NET::FTPServer' against section 4 (which does not match). The
625             result is:
626              
627             use Data::Dumper;
628             print Dumper(\%config);
629             $VAR1 = {
630             'Perl_Module' => 1,
631             'Core_Module' => 0,
632             'FTP_Module' => 0,
633             'Installed_Module' => 0,
634             };
635              
636              
637             If a C<-SectionType> is not specified in a C<-MatchSections> block, then
638             target strings of a named type will not match it.
639              
640             Matching by C<-SectionType> is used in
641             C to generate configurations
642             based both on the URL of the request and of the name of the Perl Module
643             and runmode handling the request.
644              
645             =item B<-TrimSectionNames>
646              
647             By default, section names are trimmed of leading and trailing whitespace
648             before they are used to match. This is to allow for sections like:
649              
650            
651            
652              
653             The whitespace at the end of the section name is necessary to prevent
654             Config::General's parser from thinking that the first tag is an empty
655             C<< >> block.
656              
657             # Config::General parses this as
658             # Config::General now considers this to be spurious
659              
660             If leading and trailing whitespace is significant to your matches, you
661             can disable trimming by setting -TrimSectionNames to C<0> or C.
662              
663             =item B<-MergePriority>
664              
665             Sections with a lower C<-MergePriority> are merged before sections with
666             a higher C<-MergePriority>. If two or more sections have the same
667             C<-MergePriority> they are weighted the same and they are merged
668             according to the "best match" against the target string (i.e. the
669             longest matching substring).
670              
671             See the description above under L.
672              
673             =back
674              
675             =cut
676              
677             sub new {
678 15     15 1 884 my $proto = shift;
679 15   33     120 my $class = ref $proto || $proto;
680              
681 15         74 my %args = @_;
682 15         38 my $match_sections = [];
683              
684 15 50 33     247 if (exists $args{'-MatchSections'} and ref $args{'-MatchSections'} eq 'ARRAY') {
685 15         61 $match_sections = delete $args{'-MatchSections'};
686             }
687              
688 15         242 my $self = $class->SUPER::new(%args);
689              
690 15         28148 $self->{__PACKAGE__ . '::MatchSections'} = $match_sections;
691              
692 15         51 bless $self, $class;
693 15         74 return $self;
694             }
695              
696             =head1 METHODS
697              
698             C is a subclass of C, so you
699             can use of C's methods. In particular, you can use
700             C to get the entire configuration without concern for any
701             section matching.
702              
703             =head2 getall_matching( $target_string )
704              
705             Returns the merged configuration of all sections matching
706             C<$target_string>, according to the rules set up in the
707             C<-MatchSections> in C. All C<-MatchSections> are included,
708             regardless of their C<-SectionType>.
709              
710             =head2 getall_matching( $type => $target_string )
711              
712             Returns the merged configuration matching C<$target_string>, based only
713             the C<-MatchSection>s that have a C<-SectionType> of C<$type>.
714              
715             =head2 getall_matching( $type1 => $target_string1, $type2 => $target_string2 )
716              
717             Returns the merged configuration of all sections of C<-SectionType>
718             C<$type1> matching C<$target_string1> and all sections of
719             C<-SectionType> C<$type2> matching C<$target_string2>.
720              
721             The order of the parameters to C is retained, so
722             C<$type1> sections will be matched first, followed by C<$type2>
723             sections.
724              
725             If you call C in a scalar context, you will receive a
726             reference to the config hash:
727              
728             my $config = $conf->getall_matching($target_string);
729             my $value = $config->{'somekey'};
730              
731             =cut
732              
733             sub getall_matching {
734 59     59 1 69943 my $self = shift;
735 59         279 my %config = $self->getall();
736              
737 59         735 return $self->_getall_matching_in_config(\%config, @_);
738             }
739              
740             =head2 getall_matching_nested( $level, ... )
741              
742             Behaves the same as C, except that it can match nested
743             structures.
744              
745             # stories.conf
746            
747             antagonist = Big Bad Wolf
748             moral = obey the protestant work ethic
749            
750              
751            
752            
753             antagonist = Big Bad Wolf
754             moral = appearances are deceptive
755            
756            
757              
758            
759             antagonist = Big Bad Wolf
760              
761            
762             moral = never talk to strangers
763            
764              
765            
766             moral = talk to strangers and then chop them up
767            
768            
769              
770              
771             my $conf = Config::General::Match->new(
772             -MatchSections => [
773             {
774             -Name => 'Story',
775             -MatchType => 'substring',
776             -SectionType => 'story',
777             },
778             {
779             -Name => 'Location',
780             -MatchType => 'path',
781             -SectionType => 'path',
782             },
783             ],
784             -ConfigFile => 'stories.conf',
785             );
786              
787             my $depth = 2;
788             $config = $conf->getall_matching_nested(
789             $depth,
790             story => 'Wolf in Sheep\'s Clothing',
791             path => '/aesop/wolf-in-sheeps-clothing',
792             );
793              
794             use Data::Dumper;
795             print Dumper($config);
796             $VAR1 = {
797             'antagonist' => 'Big Bad Wolf',
798             'moral' => 'appearances are deceptive'
799             };
800              
801              
802             =cut
803              
804             sub getall_matching_nested {
805 7     7 1 5972 my $self = shift;
806 7         12 my $depth = shift;
807              
808 7         29 my $config = { $self->getall() };
809              
810 7         63 for (1..$depth) {
811 14         40 $config = $self->_getall_matching_in_config($config, @_);
812             }
813 7 50       14 return %$config if wantarray;
814 7         17 return $config;
815             }
816              
817             # _getall_matching_in_config($config, ... )
818             # Behaves the same as C, except that you must explicitly
819             # provide a reference to a hash of config values as the first argument.
820             # This allows you to match against a specific configuration
821             # without the overhead of creating a new object:
822              
823             sub _getall_matching_in_config {
824 73     73   115 my $self = shift;
825 73         92 my $merged_config = shift;
826              
827 73         118 my $target_string;
828             my $section_type;
829              
830 0         0 my @matches;
831              
832 73         215 while (@_) {
833 94 100       229 if (@_ == 1) {
834 47         66 $target_string = shift;
835 47         59 $section_type = undef;
836             }
837             else {
838 47         62 $section_type = shift;
839 47         70 $target_string = shift;
840             }
841 94         270 push @matches, $self->_get_matching_sections($merged_config, $target_string, $section_type);
842             }
843              
844             # Now sort the matching sections, first by MergePriority (lowest
845             # first), second by length of the matching substring (shortest first)
846             #
847             # @matches contains a list of array refs whose first element is the
848             # section's MergePriority, the second element is the number of
849             # characters that matched, and the third element is the config hash
850             # of the matching section
851              
852 73 50       244 foreach my $match (sort { $a->[0] <=> $b->[0] || $a->[1] <=> $b->[1] } @matches) {
  66         222  
853              
854 87         24247 my $section_hash = $match->[2];
855              
856 87         287 $merged_config = Hash::Merge::merge($section_hash, $merged_config);
857              
858             }
859              
860 73 100       49363 return %$merged_config if wantarray;
861 14         47 return $merged_config;
862             }
863              
864             sub _get_matching_sections {
865 94     94   125 my $self = shift;
866 94         117 my $config = shift;
867              
868 94         159 my ($target_string, $target_section_type) = @_;
869              
870 94         150 my $match_sections = $self->{__PACKAGE__ . '::MatchSections'};
871              
872             # validation of -MatchSections
873 94 50 33     728 unless ($match_sections and ref $match_sections eq 'ARRAY' and @$match_sections) {
      33        
874 0         0 croak "Can't run getall_matching when no -MatchSections provided";
875             }
876              
877 94         186 my %allowed_spec_keys = map { $_ => 1 } qw(
  564         1190  
878             -Name
879             -MatchType
880             -PathSeparator
881             -SectionType
882             -MergePriority
883             -TrimSectionNames
884             );
885              
886 94         194 my @matches;
887              
888             my $count;
889 94         173 foreach my $spec (@$match_sections) {
890 224         271 $count++;
891              
892 224         516 my @bad_spec_keys = grep { !$allowed_spec_keys{$_} } keys %$spec;
  708         1321  
893 224 50       517 if (@bad_spec_keys) {
894 0         0 croak "Unknown spec option(s): ".(join ', ', @bad_spec_keys);
895             }
896              
897             # Must have name and MatchType
898 224 50       539 my $name = $spec->{'-Name'} or croak "Spec #$count has no -Name";
899 224 50       546 my $match_type = $spec->{'-MatchType'} or croak "Spec #$count has no -MatchType";
900 224   100     716 my $path_sep = $spec->{'-PathSeparator'} || '/';
901 224   100     892 my $section_priority = $spec->{'-MergePriority'} || 0;
902 224         298 my $this_section_type = $spec->{'-SectionType'};
903              
904 224 100       464 my $trim_section_names = exists $spec->{'-TrimSectionNames'} ? $spec->{'-TrimSectionNames'} : 1;
905              
906 224 100       513 if ($self->{'LowerCaseNames'}) {
907 2         4 $name = lc $name;
908 2         210 $this_section_type = lc $this_section_type;
909             }
910              
911             # Skip this section if the section's type does not match the type
912             # of the target string. But only do so if the target_string has a type.
913 224 100       435 if ($target_section_type) {
914              
915             # If the target_string has a type but the section doesn't then skip
916 127 50       294 next unless $this_section_type;
917              
918             # If the target_string doesn't equal the section string then skip
919 127 100       248 if ($target_section_type ne $this_section_type) {
920 71         165 next;
921             }
922             }
923              
924 153 100       342 next unless exists $config->{$name};
925              
926 142         244 my $sections = delete $config->{$name};
927              
928              
929 142         337 foreach my $section_string (keys %$sections) {
930 227         312 my $section_hash = $sections->{$section_string};
931              
932 227 100       461 if ($trim_section_names) {
933 223         1239 $section_string =~ s/^\s*(.*?)\s*$/$1/;
934             }
935              
936 227 100 66     1154 if ($match_type =~ /^exact$/i) {
    100          
    100          
    50          
937 34 100       119 if ($target_string eq $section_string) {
938             # store matches as array ref where first element is
939             # the section's MergePriority, the second element is
940             # the length and the third is the config hash of
941             # matching section
942              
943 5         30 push @matches, [
944             $section_priority,
945             length($section_string),
946             $section_hash,
947             ];
948             }
949             }
950             elsif ($match_type =~ /^substring$/i) {
951 15 100   15   15599 if ((index $target_string, $section_string) != ($[ - 1)) {
  15         7760  
  15         5832  
  46         331  
952             # store matches as array ref where first element is
953             # the section's MergePriority, the second element is
954             # the length and the third is the config hash of
955             # matching section
956              
957 25         126 push @matches, [
958             $section_priority,
959             length($section_string),
960             $section_hash,
961             ];
962             }
963             }
964             elsif ($match_type =~ /^regex$/i) {
965 53         556 my $regex = qr/$section_string/;
966 53 100       789 if ($target_string =~ qr/($section_string)/) {
967             # store matches as array ref where first element is
968             # the section's MergePriority, the second element is
969             # the length and the third is the config hash of
970             # matching section
971              
972 23         144 push @matches, [
973             $section_priority,
974             length($1),
975             $section_hash,
976             ];
977             }
978             }
979             elsif ($match_type =~ /^path$/i or $match_type =~ /^hierarchy$/i) {
980              
981 94         167 my $regex = quotemeta($section_string);
982              
983             # If the section string ends with $path_sep then
984             # we have only to match the whole string
985              
986 94 100 100     2799 if (($section_string =~ /$path_sep$/ and $target_string =~ qr/^($regex)/)
      100        
987              
988             # otherwise, we have to find the section_string either at
989             # the end of target_string or immediately followed by
990             # $path_sep in target string
991              
992             or ($target_string =~ qr/^($regex)(?:$path_sep|$)/)) {
993             # store matches as array ref where first element is
994             # the section's MergePriority, the second element is
995             # the length and the third is the config hash of
996             # matching section
997              
998 34         227 push @matches, [
999             $section_priority,
1000             length($1),
1001             $section_hash,
1002             ];
1003             }
1004             }
1005             else {
1006 0         0 croak "Bad -MatchType: $match_type";
1007             }
1008             }
1009             }
1010 94         455 return @matches;
1011             }
1012              
1013             =head1 Changing Hash::Merge behaviour
1014              
1015             Matching sections are merged together using the C module.
1016             If you want to change how this module does its work you can call
1017             subroutines in the C package directly. For instance, to
1018             change the merge strategy so that earlier sections have precidence over
1019             later sections, you could call:
1020              
1021             # Note American Spelling :)
1022             Hash::Merge::set_behavior('RIGHT_PRECEDENT')
1023              
1024             You should do this before you call C.
1025              
1026             For more information on how to change merge options, see the
1027             C docs.
1028              
1029             =head1 AUTHOR
1030              
1031             Michael Graham, C<< >>
1032              
1033             =head1 BUGS
1034              
1035             =over 4
1036              
1037             =item *
1038              
1039             This module does not support the functional interface to
1040             C (e.g. C).
1041              
1042             =item *
1043              
1044             This module only supports the following constructor form:
1045              
1046             my $self = Config::General::Match->new( %options );
1047              
1048             It does not support the other two C constructor styles:
1049              
1050             # NOT supported
1051             my $self = Config::General->new( "rcfile" );
1052             my $self = Config::General->new( \%some_hash );
1053              
1054             =back
1055              
1056             Please report any bugs or feature requests to
1057             C, or through the web interface at
1058             L. I will be notified, and then you'll automatically
1059             be notified of progress on your bug as I make changes.
1060              
1061             =head1 SEE ALSO
1062              
1063             Config::General
1064             CGI::Application::Plugin::Config::General
1065             Hash::Merge
1066              
1067             =head1 ACKNOWLEDGEMENTS
1068              
1069             This module would not be possible without Thomas Linden's excellent
1070             C module.
1071              
1072             =head1 COPYRIGHT & LICENSE
1073              
1074             Copyright 2004-2005 Michael Graham, All Rights Reserved.
1075              
1076             This program is free software; you can redistribute it and/or modify it
1077             under the same terms as Perl itself.
1078              
1079             =cut
1080              
1081             1;
1082              
1083