File Coverage

blib/lib/PPIx/Regexp.pm
Criterion Covered Total %
statement 117 119 98.3
branch 41 50 82.0
condition 12 12 100.0
subroutine 29 30 96.6
pod 18 18 100.0
total 217 229 94.7


line stmt bran cond sub pod time code
1             =head1 NAME
2              
3             PPIx::Regexp - Represent a regular expression of some sort
4              
5             =head1 SYNOPSIS
6              
7             use PPIx::Regexp;
8             use PPIx::Regexp::Dumper;
9             my $re = PPIx::Regexp->new( 'qr{foo}smx' );
10             PPIx::Regexp::Dumper->new( $re )
11             ->print();
12              
13             =head1 DEPRECATION NOTICE
14              
15             The C argument to L is retracted, and
16             postfix dereferences are always be recognized.
17              
18             Starting with version 0.074_01, the first use of this argument warned.
19             With version 0.079_01, all uses warned. With version 0.080_01,
20             all uses became fatal. With version 0.084_01, all mention of this
21             argument was removed, except for this notice.
22              
23             =head1 INHERITANCE
24              
25             C is a L.
26              
27             C has no descendants.
28              
29             =head1 DESCRIPTION
30              
31             The purpose of the F package is to parse regular
32             expressions in a manner similar to the way the L package parses
33             Perl. This class forms the root of the parse tree, playing a role
34             similar to L.
35              
36             This package shares with L the property of being round-trip
37             safe. That is,
38              
39             my $expr = 's/ ( \d+ ) ( \D+ ) /$2$1/smxg';
40             my $re = PPIx::Regexp->new( $expr );
41             print $re->content() eq $expr ? "yes\n" : "no\n"
42              
43             should print 'yes' for any valid regular expression.
44              
45             Navigation is similar to that provided by L. That is to say,
46             things like C, C, C and so on all
47             work pretty much the same way as in L.
48              
49             The class hierarchy is also similar to L. Except for some
50             utility classes (the dumper, the lexer, and the tokenizer) all classes
51             are descended from L, which
52             provides basic navigation. Tokens are descended from
53             L, which provides content. All
54             containers are descended from L,
55             which provides for children, and all structure elements are descended
56             from L, which provides
57             beginning and ending delimiters, and a type.
58              
59             There are two features of L that this package does not provide
60             - mutability and operator overloading. There are no plans for serious
61             mutability, though something like L's C functionality
62             might be considered. Similarly there are no plans for operator
63             overloading, which appears to the author to represent a performance hit
64             for little tangible gain.
65              
66             =head1 NOTICE
67              
68             The author will attempt to preserve the documented interface, but if the
69             interface needs to change to correct some egregiously bad design or
70             implementation decision, then it will change. Any incompatible changes
71             will go through a deprecation cycle.
72              
73             The goal of this package is to parse well-formed regular expressions
74             correctly. A secondary goal is not to blow up on ill-formed regular
75             expressions. The correct identification and characterization of
76             ill-formed regular expressions is B a goal of this package, nor is
77             the consistent parsing of ill-formed regular expressions from release to
78             release.
79              
80             This policy attempts to track features in development releases as well
81             as public releases. However, features added in a development release and
82             then removed before the next production release B be tracked,
83             and any functionality relating to such features B. The
84             issue here is the potential re-use (with different semantics) of syntax
85             that did not make it into the production release.
86              
87             From time to time the Perl regular expression engine changes in ways
88             that change the parse of a given regular expression. When these changes
89             occur, C will be changed to produce the more modern parse.
90             Known examples of this include:
91              
92             =over
93              
94             =item C<$(> no longer interpolates as of Perl 5.005, per C.
95              
96             Newer Perls seem to parse this as C (i.e. an end-of-string or
97             newline assertion) followed by an open parenthesis, and that is what
98             C does.
99              
100             =item C<$)> and C<$|> also seem to parse as the C<$> assertion
101              
102             followed by the relevant meta-character, though I have no documentation
103             reference for this.
104              
105             =item C<@+> and C<@-> no longer interpolate as of Perl 5.9.4
106              
107             per C. Subsequent Perls treat C<@+> as a quantified
108             literal and C<@-> as two literals, and that is what C
109             does. Note that subscripted references to these arrays B
110             interpolate, and are so parsed by C.
111              
112             =item Only space and horizontal tab are whitespace as of Perl 5.23.4
113              
114             when inside a bracketed character class inside an extended bracketed
115             character class, per C. Formerly any white space
116             character parsed as whitespace. This change in C will be
117             reverted if the change in Perl does not make it into Perl 5.24.0.
118              
119             =item Unescaped literal left curly brackets
120              
121             These are being removed in positions where quantifiers are legal, so
122             that they can be used for new functionality. Some of them are gone in
123             5.25.1, others will be removed in a future version of Perl. In
124             situations where they have been removed,
125             L
126             will return the version in which they were removed. When the new
127             functionality appears, the parse produced by this software will reflect
128             the new functionality.
129              
130             B that the situation with a literal left curly after a literal
131             character is complicated. It was made an error in Perl 5.25.1, and
132             remained so through all 5.26 releases, but became a warning again in
133             5.27.1 due to its use in GNU Autoconf. Whether it will ever become
134             illegal again is not clear to me based on the contents of
135             F. At the moment
136             L
137             returns C, but obviously that is not the whole story, and methods
138             L and
139             L
140             were introduced to deal with this complication.
141              
142             =item C<\o{...}>
143              
144             is parsed as the octal equivalent of C<\x{...}>. This is its meaning as
145             of perl 5.13.2. Before 5.13.2 it was simply literal C<'o'> and so on.
146              
147             =item C
148              
149             (with first count omitted) is allowed as a quantifier as of Perl 5.33.6.
150             The previous parse made this all literals.
151              
152             =item C
153              
154             (with spaces inside but adjacent to curly brackets, or around the comma
155             if any) is allowed as a quantifier as of Perl 5.33.6. The previous parse
156             made this all literals.
157              
158             =back
159              
160             There are very probably other examples of this. When they come to light
161             they will be documented as producing the modern parse, and the code
162             modified to produce this parse if necessary.
163              
164             =head1 METHODS
165              
166             This class provides the following public methods. Methods not documented
167             here are private, and unsupported in the sense that the author reserves
168             the right to change or remove them without notice.
169              
170             =cut
171              
172             package PPIx::Regexp;
173              
174 9     9   311387 use strict;
  9         40  
  9         254  
175 9     9   47 use warnings;
  9         50  
  9         270  
176              
177 9     9   56 use base qw{ PPIx::Regexp::Node };
  9         16  
  9         4703  
178              
179 9     9   60 use Carp;
  9         17  
  9         538  
180 9         909 use PPIx::Regexp::Constant qw{
181             ARRAY_REF
182             LOCATION_LINE
183             LOCATION_CHARACTER
184             LOCATION_COLUMN
185             LOCATION_LOGICAL_LINE
186             LOCATION_LOGICAL_FILE
187             @CARP_NOT
188 9     9   80 };
  9         19  
189 9     9   4650 use PPIx::Regexp::Lexer ();
  9         38  
  9         301  
190 9     9   68 use PPIx::Regexp::Token::Modifier (); # For its modifier manipulations.
  9         21  
  9         188  
191 9     9   47 use PPIx::Regexp::Tokenizer;
  9         21  
  9         352  
192 9         480 use PPIx::Regexp::Util qw{
193             __choose_tokenizer_class
194             __instance
195 9     9   52 };
  9         18  
196 9     9   54 use Scalar::Util qw{ refaddr };
  9         24  
  9         15055  
197              
198             our $VERSION = '0.087_01';
199              
200             =head2 new
201              
202             my $re = PPIx::Regexp->new('/foo/');
203              
204             This method instantiates a C object from a string, a
205             L, a
206             L, or a
207             L.
208             Honestly, any L will work, but only the three
209             Regexp classes mentioned previously are likely to do anything useful.
210              
211             Whatever form the argument takes, it is assumed to consist entirely of a
212             valid match, substitution, or C<< qr<> >> string.
213              
214             Optionally you can pass one or more name/value pairs after the regular
215             expression. The possible options are:
216              
217             =over
218              
219             =item default_modifiers array_reference
220              
221             This option specifies a reference to an array of default modifiers to
222             apply to the regular expression being parsed. Each modifier is specified
223             as a string. Any actual modifiers found supersede the defaults.
224              
225             When applying the defaults, C<'?'> and C<'/'> are completely ignored,
226             and C<'^'> is ignored unless it occurs at the beginning of the modifier.
227             The first dash (C<'-'>) causes subsequent modifiers to be negated.
228              
229             So, for example, if you wish to produce a C object
230             representing the regular expression in
231              
232             use re '/smx';
233             {
234             no re '/x';
235             m/ foo /;
236             }
237              
238             you would (after some help from L in finding the relevant
239             statements), do something like
240              
241             my $re = PPIx::Regexp->new( 'm/ foo /',
242             default_modifiers => [ '/smx', '-/x' ] );
243              
244             =item encoding name
245              
246             This option specifies the encoding of the regular expression. This is
247             passed to the tokenizer, which will C the regular expression
248             string before it tokenizes it. For example:
249              
250             my $re = PPIx::Regexp->new( '/foo/',
251             encoding => 'iso-8859-1',
252             );
253              
254             =item index_locations Boolean
255              
256             This Boolean option specifies whether the locations of the elements in
257             the regular expression should be indexed.
258              
259             If unspecified or specified as C a default value is used. This
260             default is true if the argument is a L or the
261             C option was specified. Otherwise the default is false.
262              
263             =item location array_reference
264              
265             This option specifies the location of the new object in the document
266             from which it was created. It is a reference to a five-element array
267             compatible with that returned by the C method of
268             L.
269              
270             If not specified, the location of the original string is used if it was
271             specified as a L.
272              
273             If no location can be determined, the various C methods will
274             return C.
275              
276             =item postderef Boolean
277              
278             B.
279             See L above for the details.
280              
281             This option is passed on to the tokenizer, where it specifies whether
282             postfix dereferences are recognized in interpolations and code. This
283             experimental feature was introduced in Perl 5.19.5.
284              
285             As of version 0.074_01, the default is true. Through release 0.074, the
286             default was the value of
287             C<$PPIx::Regexp::Tokenizer::DEFAULT_POSTDEREF>, which was true. When
288             originally introduced this was false, but was documented as becoming
289             true when and if postfix dereferencing became mainstream. The intent to
290             mainstream was announced with Perl 5.23.1, and became official (so to
291             speak) with Perl 5.24.0, so the default became true with L
292             0.049_01.
293              
294             Note that if L starts unconditionally recognizing postfix
295             dereferences, this argument will immediately become ignored, and will be
296             put through a deprecation cycle and removed.
297              
298             =item strict Boolean
299              
300             This option is passed on to the tokenizer and lexer, where it specifies
301             whether the parse should assume C is in effect.
302              
303             The C<'strict'> pragma was introduced in Perl 5.22, and its
304             documentation says that it is experimental, and that there is no
305             commitment to backward compatibility. The same applies to the
306             parse produced when this option is asserted. Also, the usual caveat
307             applies: if C ends up being retracted, this option and
308             all related functionality will be also.
309              
310             Given the nature of C, you should expect that if you
311             assert this option, regular expressions that previously parsed without
312             error might no longer do so. If an element ends up being declared an
313             error because this option is set, its C will
314             be the Perl version at which C started rejecting these
315             elements.
316              
317             The default is false.
318              
319             =item trace number
320              
321             If greater than zero, this option causes trace output from the parse.
322             The author reserves the right to change or eliminate this without
323             notice.
324              
325             =back
326              
327             Passing optional input other than the above is not an error, but neither
328             is it supported.
329              
330             =cut
331              
332             {
333              
334             my $errstr;
335              
336             sub new {
337 333     333 1 16300 my ( $class, $content, %args ) = @_;
338 333 50       1182 ref $class and $class = ref $class;
339              
340             # We have to do this very early so the tokenizer can see it.
341             defined $args{index_locations}
342             or $args{index_locations} = (
343 333 50 100     2725 !! $args{location} || __instance( $content, 'PPI::Element' ) );
344              
345 333         929 $errstr = undef;
346              
347             # As of 0.068_01 this either fails or returns
348             # PPIx::Regexp::Tokenizer
349 333         1582 my $tokenizer_class = __choose_tokenizer_class( $content, \%args );
350              
351             my $tokenizer = $tokenizer_class->new(
352 333 100       2269 $content, %args ) or do {
353 1         4 $errstr = PPIx::Regexp::Tokenizer->errstr();
354 1         4 return;
355             };
356              
357 332         2224 my $lexer = PPIx::Regexp::Lexer->new( $tokenizer, %args );
358 332         1493 my @nodes = $lexer->lex();
359 332         1385 my $self = $class->SUPER::__new( @nodes );
360 332         1171 $self->{index_locations} = $args{index_locations};
361 332         1271 $self->{source} = $content;
362 332         1444 $self->{failures} = $lexer->failures();
363             $self->{effective_modifiers} =
364 332         1464 $tokenizer->__effective_modifiers();
365 332 100       1241 if ( $args{location} ) {
366             ARRAY_REF eq ref $args{location}
367 1 50       227 or croak q;
368 1         5 foreach my $inx ( 0 .. 3 ) {
369 4 50       151 $args{location}[$inx] =~ m/ [^0-9] /smx
370             and croak "Argument 'location' element $inx must be an unsigned integer";
371             }
372 1         6 $self->{location} = $args{location};
373             }
374 332         4980 return $self;
375             }
376              
377             sub errstr {
378 2     2 1 5 return $errstr;
379             }
380              
381             }
382              
383             =head2 new_from_cache
384              
385             This static method wraps L in a caching mechanism. Only one object
386             will be generated for a given L, no matter
387             how many times this method is called. Calls after the first for a given
388             L simply return the same C
389             object.
390              
391             When the C object is returned from cache, the values of
392             the optional arguments are ignored.
393              
394             Calls to this method with the regular expression in a string rather than
395             a L will not be cached.
396              
397             B This method is provided for code like
398             L which might instantiate the same object
399             multiple times. The cache will persist until L is called.
400              
401             =head2 flush_cache
402              
403             $re->flush_cache(); # Remove $re from cache
404             PPIx::Regexp->flush_cache(); # Empty the cache
405              
406             This method flushes the cache used by L. If called as a
407             static method with no arguments, the entire cache is emptied. Otherwise
408             any objects specified are removed from the cache.
409              
410             =cut
411              
412             {
413              
414             my %cache;
415              
416             our $DISABLE_CACHE; # Leave this undocumented, at least for
417             # now.
418              
419             sub __cache_size {
420 8     8   136 return scalar keys %cache;
421             }
422              
423             sub new_from_cache {
424 6     6 1 8463 my ( $class, $content, %args ) = @_;
425              
426 6 100       41 __instance( $content, 'PPI::Element' )
427             or return $class->new( $content, %args );
428              
429 5 100       34 $DISABLE_CACHE and return $class->new( $content, %args );
430              
431 3         12 my $addr = refaddr( $content );
432 3 100       18 exists $cache{$addr} and return $cache{$addr};
433              
434 2 50       15 my $self = $class->new( $content, %args )
435             or return;
436              
437 2         9 $cache{$addr} = $self;
438              
439 2         22 return $self;
440              
441             }
442              
443             sub flush_cache {
444 4     4 1 7281 my @args = @_;
445              
446 4 100       31 ref $args[0] or shift @args;
447              
448 4 100       27 if ( @args ) {
449 3         16 foreach my $obj ( @args ) {
450 3 100 100     22 if ( __instance( $obj, __PACKAGE__ ) &&
451             __instance( ( my $parent = $obj->source() ),
452             'PPI::Element' ) ) {
453 1         12 delete $cache{ refaddr( $parent ) };
454             }
455             }
456             } else {
457 1         7 %cache = ();
458             }
459 4         21 return;
460             }
461              
462             }
463              
464 0     0 1 0 sub can_be_quantified { return; }
465              
466             =head2 capture_names
467              
468             foreach my $name ( $re->capture_names() ) {
469             print "Capture name '$name'\n";
470             }
471              
472             This convenience method returns the capture names found in the regular
473             expression.
474              
475             This method is equivalent to
476              
477             $self->regular_expression()->capture_names();
478              
479             except that if C<< $self->regular_expression() >> returns C
480             (meaning that something went terribly wrong with the parse) this method
481             will simply return.
482              
483             =cut
484              
485             sub capture_names {
486 3     3 1 14 my ( $self ) = @_;
487 3 100       9 my $re = $self->regular_expression() or return;
488 2         9 return $re->capture_names();
489             }
490              
491             =head2 delimiters
492              
493             print join("\t", PPIx::Regexp->new('s/foo/bar/')->delimiters());
494             # prints '// //'
495              
496             When called in list context, this method returns either one or two
497             strings, depending on whether the parsed expression has a replacement
498             string. In the case of non-bracketed substitutions, the start delimiter
499             of the replacement string is considered to be the same as its finish
500             delimiter, as illustrated by the above example.
501              
502             When called in scalar context, you get the delimiters of the regular
503             expression; that is, element 0 of the array that is returned in list
504             context.
505              
506             Optionally, you can pass an index value and the corresponding delimiters
507             will be returned; index 0 represents the regular expression's
508             delimiters, and index 1 represents the replacement string's delimiters,
509             which may be undef. For example,
510              
511             print PPIx::Regexp->new('s{foo}')->delimiters(1);
512             # prints '<>'
513              
514             If the object was not initialized with a valid regexp of some sort, the
515             results of this method are undefined.
516              
517             =cut
518              
519             sub delimiters {
520 63     63 1 192 my ( $self, $inx ) = @_;
521              
522 63         213 my @rslt;
523 63         147 foreach my $method ( qw{ regular_expression replacement } ) {
524 126 100       505 defined ( my $obj = $self->$method() ) or next;
525 68         442 push @rslt, $obj->delimiters();
526             }
527              
528 63 100       238 defined $inx and return $rslt[$inx];
529 57 50       170 wantarray and return @rslt;
530 57 50       365 defined wantarray and return $rslt[0];
531 0         0 return;
532             }
533              
534             =head2 errstr
535              
536             This static method returns the error string from the most recent attempt
537             to instantiate a C. It will be C if the most recent
538             attempt succeeded.
539              
540             =cut
541              
542             # defined above, just after sub new.
543              
544             sub explain {
545 1     1 1 3 return;
546             }
547              
548             =head2 extract_regexps
549              
550             my $doc = PPI::Document->new( $path );
551             $doc->index_locations();
552             my @res = PPIx::Regexp->extract_regexps( $doc )
553              
554             This convenience (well, sort-of) static method takes as its argument a
555             L object and returns C
556             objects corresponding to all regular expressions found in it, in the
557             order in which they occur in the document. You will need to keep a
558             reference to the original L object if you
559             wish to be able to recover the original L
560             objects via the L
561             L method.
562              
563             =cut
564              
565             sub extract_regexps {
566 2     2 1 168396 my ( $class, $doc ) = @_;
567 2 100       9 my @found = map { @{ $doc->find( $_ ) || [] } } qw{
  6         67280  
  6         27  
568             PPI::Token::QuoteLike::Regexp
569             PPI::Token::Regexp::Match
570             PPI::Token::Regexp::Substitute
571             };
572 3         15 return ( map { $class->new( $_ ) } map { $_->[0] }
  3         246  
573 1 50       41 sort { $a->[1][0] <=> $b->[1][0] || $a->[1][1] <=> $b->[1][1] }
574 2         33379 map { [ $_, $_->location() ] }
  3         37660  
575             @found
576             );
577             }
578              
579             =head2 failures
580              
581             print "There were ", $re->failures(), " parse failures\n";
582              
583             This method returns the number of parse failures. This is a count of the
584             number of unknown tokens plus the number of unterminated structures plus
585             the number of unmatched right brackets of any sort.
586              
587             =cut
588              
589             sub failures {
590 285     285 1 841 my ( $self ) = @_;
591 285         789 return $self->{failures};
592             }
593              
594             =head2 max_capture_number
595              
596             print "Highest used capture number ",
597             $re->max_capture_number(), "\n";
598              
599             This convenience method returns the highest capture number used by the
600             regular expression. If there are no captures, the return will be 0.
601              
602             This method is equivalent to
603              
604             $self->regular_expression()->max_capture_number();
605              
606             except that if C<< $self->regular_expression() >> returns C
607             (meaning that something went terribly wrong with the parse) this method
608             will too.
609              
610             =cut
611              
612             sub max_capture_number {
613 6     6 1 15 my ( $self ) = @_;
614 6 100       21 my $re = $self->regular_expression() or return;
615 5         19 return $re->max_capture_number();
616             }
617              
618             =head2 modifier
619              
620             my $re = PPIx::Regexp->new( 's/(foo)/${1}bar/smx' );
621             print $re->modifier()->content(), "\n";
622             # prints 'smx'.
623              
624             This method retrieves the modifier of the object. This comes from the
625             end of the initializing string or object and will be a
626             L.
627              
628             B that this object represents the actual modifiers present on the
629             regexp, and does not take into account any that may have been applied by
630             default (i.e. via the C argument to C). For
631             something that takes account of default modifiers, see
632             L, below.
633              
634             In the event of a parse failure, there may not be a modifier present, in
635             which case nothing is returned.
636              
637             =cut
638              
639             sub modifier {
640 3     3 1 14 my ( $self ) = @_;
641 3         12 return $self->_component( 'PPIx::Regexp::Token::Modifier' );
642             }
643              
644             =head2 modifier_asserted
645              
646             my $re = PPIx::Regexp->new( '/ . /',
647             default_modifiers => [ 'smx' ] );
648             print $re->modifier_asserted( 'x' ) ? "yes\n" : "no\n";
649             # prints 'yes'.
650              
651             This method returns true if the given modifier is asserted for the
652             regexp, whether explicitly or by the modifiers passed in the
653             C argument.
654              
655             Starting with version 0.036_01, if the argument is a
656             single-character modifier followed by an asterisk (intended as a wild
657             card character), the return is the number of times that modifier
658             appears. In this case an exception will be thrown if you specify a
659             multi-character modifier (e.g. C<'ee*'>), or if you specify one of the
660             match semantics modifiers (e.g. C<'a*'>).
661              
662             =cut
663              
664             sub modifier_asserted {
665 15     15 1 45 my ( $self, $modifier ) = @_;
666             return PPIx::Regexp::Token::Modifier::__asserts(
667             $self->{effective_modifiers},
668 15         58 $modifier,
669             );
670             }
671              
672             # This is a kluge for both determining whether the object asserts
673             # modifiers (hence the 'ductype') and determining whether the given
674             # modifier is actually asserted. The signature is the invocant and the
675             # modifier name, which must not be undef. The return is a Boolean.
676             *__ducktype_modifier_asserted = \&modifier_asserted;
677              
678             # As of Perl 5.21.1 you can not leave off the type of a '?'-delimited
679             # regexp. Because this is not associated with any single child we
680             # compute it here.
681             sub perl_version_removed {
682 56     56 1 148 my ( $self ) = @_;
683 56         250 my $v = $self->SUPER::perl_version_removed();
684 56 100 100     254 defined $v
685             and $v <= 5.021001
686             and return $v;
687 55 50       275 defined( my $delim = $self->delimiters() )
688             or return $v;
689 55 100 100     200 '??' eq $delim
690             and '' eq $self->type()->content()
691             and return '5.021001';
692 54         171 return $v;
693             }
694              
695             =head2 regular_expression
696              
697             my $re = PPIx::Regexp->new( 's/(foo)/${1}bar/smx' );
698             print $re->regular_expression()->content(), "\n";
699             # prints '/(foo)/'.
700              
701             This method returns that portion of the object which actually represents
702             a regular expression.
703              
704             =cut
705              
706             sub regular_expression {
707 78     78 1 173 my ( $self ) = @_;
708 78         304 return $self->_component( 'PPIx::Regexp::Structure::Regexp' );
709             }
710              
711             =head2 replacement
712              
713             my $re = PPIx::Regexp->new( 's/(foo)/${1}bar/smx' );
714             print $re->replacement()->content(), "\n";
715             # prints '${1}bar/'.
716              
717             This method returns that portion of the object which represents the
718             replacement string. This will be C unless the regular expression
719             actually has a replacement string. Delimiters will be included, but
720             there will be no beginning delimiter unless the regular expression was
721             bracketed.
722              
723             =cut
724              
725             sub replacement {
726 65     65 1 153 my ( $self ) = @_;
727 65         146 return $self->_component( 'PPIx::Regexp::Structure::Replacement' );
728             }
729              
730             =head2 source
731              
732             my $source = $re->source();
733              
734             This method returns the object or string that was used to instantiate
735             the object.
736              
737             =cut
738              
739             sub source {
740 5     5 1 29 my ( $self ) = @_;
741 5         25 return $self->{source};
742             }
743              
744             =head2 type
745              
746             my $re = PPIx::Regexp->new( 's/(foo)/${1}bar/smx' );
747             print $re->type()->content(), "\n";
748             # prints 's'.
749              
750             This method retrieves the type of the object. This comes from the
751             beginning of the initializing string or object, and will be a
752             L
753             whose C is one of 's',
754             'm', 'qr', or ''.
755              
756             =cut
757              
758             sub type {
759 4     4 1 22 my ( $self ) = @_;
760 4         11 return $self->_component( 'PPIx::Regexp::Token::Structure' );
761             }
762              
763             sub _component {
764 150     150   306 my ( $self, $class ) = @_;
765 150         396 foreach my $elem ( $self->children() ) {
766 371 100       1732 $elem->isa( $class ) and return $elem;
767             }
768 60         241 return;
769             }
770              
771             1;
772              
773             __END__