| Filename | /Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/PPIx/Regexp/Element.pm |
| Statements | Executed 22 statements in 1.24ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 322µs | 840µs | PPIx::Regexp::Element::BEGIN@43 |
| 1 | 1 | 1 | 237µs | 430µs | PPIx::Regexp::Element::BEGIN@40 |
| 1 | 1 | 1 | 12µs | 23µs | PPIx::Regexp::Element::BEGIN@33 |
| 1 | 1 | 1 | 10µs | 10µs | PPIx::Regexp::Element::BEGIN@36 |
| 1 | 1 | 1 | 9µs | 175µs | PPIx::Regexp::Element::BEGIN@39 |
| 1 | 1 | 1 | 8µs | 38µs | PPIx::Regexp::Element::BEGIN@38 |
| 1 | 1 | 1 | 7µs | 30µs | PPIx::Regexp::Element::BEGIN@41 |
| 1 | 1 | 1 | 7µs | 11µs | PPIx::Regexp::Element::BEGIN@34 |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::DESTROY |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::__ANON__[:407] |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::__PPIX_LEXER__record_capture_number |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::__error |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::__impose_defaults |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::_my_inx |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::_parent |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::_parent_keys |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::ancestor_of |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::can_be_quantified |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::class |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::comment |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::content |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::descendant_of |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::error |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::is_quantifier |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::modifier_asserted |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::nav |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::next_sibling |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::parent |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::perl_version_introduced |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::perl_version_removed |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::previous_sibling |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::significant |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::snext_sibling |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::sprevious_sibling |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::tokens |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::top |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::unescaped_content |
| 0 | 0 | 0 | 0s | 0s | PPIx::Regexp::Element::whitespace |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | =head1 NAME | ||||
| 2 | |||||
| 3 | PPIx::Regexp::Element - Base of the PPIx::Regexp hierarchy. | ||||
| 4 | |||||
| 5 | =head1 SYNOPSIS | ||||
| 6 | |||||
| 7 | No user-serviceable parts inside. | ||||
| 8 | |||||
| 9 | =head1 INHERITANCE | ||||
| 10 | |||||
| 11 | C<PPIx::Regexp::Element> is not descended from any other class. | ||||
| 12 | |||||
| 13 | C<PPIx::Regexp::Element> is the parent of | ||||
| 14 | L<PPIx::Regexp::Node|PPIx::Regexp::Node> and | ||||
| 15 | L<PPIx::Regexp::Token|PPIx::Regexp::Token>. | ||||
| 16 | |||||
| 17 | =head1 DESCRIPTION | ||||
| 18 | |||||
| 19 | This class is the base of the L<PPIx::Regexp|PPIx::Regexp> | ||||
| 20 | object hierarchy. It provides the same kind of navigational | ||||
| 21 | functionality that is provided by L<PPI::Element|PPI::Element>. | ||||
| 22 | |||||
| 23 | =head1 METHODS | ||||
| 24 | |||||
| 25 | This class provides the following public methods. Methods not documented | ||||
| 26 | here are private, and unsupported in the sense that the author reserves | ||||
| 27 | the right to change or remove them without notice. | ||||
| 28 | |||||
| 29 | =cut | ||||
| 30 | |||||
| 31 | package PPIx::Regexp::Element; | ||||
| 32 | |||||
| 33 | 2 | 19µs | 2 | 35µs | # spent 23µs (12+11) within PPIx::Regexp::Element::BEGIN@33 which was called:
# once (12µs+11µs) by base::import at line 33 # spent 23µs making 1 call to PPIx::Regexp::Element::BEGIN@33
# spent 11µs making 1 call to strict::import |
| 34 | 2 | 19µs | 2 | 16µs | # spent 11µs (7+4) within PPIx::Regexp::Element::BEGIN@34 which was called:
# once (7µs+4µs) by base::import at line 34 # spent 11µs making 1 call to PPIx::Regexp::Element::BEGIN@34
# spent 4µs making 1 call to warnings::import |
| 35 | |||||
| 36 | 2 | 40µs | 1 | 10µs | # spent 10µs within PPIx::Regexp::Element::BEGIN@36 which was called:
# once (10µs+0s) by base::import at line 36 # spent 10µs making 1 call to PPIx::Regexp::Element::BEGIN@36 |
| 37 | |||||
| 38 | 2 | 26µs | 2 | 68µs | # spent 38µs (8+30) within PPIx::Regexp::Element::BEGIN@38 which was called:
# once (8µs+30µs) by base::import at line 38 # spent 38µs making 1 call to PPIx::Regexp::Element::BEGIN@38
# spent 30µs making 1 call to Exporter::import |
| 39 | 2 | 25µs | 2 | 340µs | # spent 175µs (9+166) within PPIx::Regexp::Element::BEGIN@39 which was called:
# once (9µs+166µs) by base::import at line 39 # spent 175µs making 1 call to PPIx::Regexp::Element::BEGIN@39
# spent 166µs making 1 call to Exporter::Tiny::import |
| 40 | 2 | 86µs | 2 | 457µs | # spent 430µs (237+194) within PPIx::Regexp::Element::BEGIN@40 which was called:
# once (237µs+194µs) by base::import at line 40 # spent 430µs making 1 call to PPIx::Regexp::Element::BEGIN@40
# spent 27µs making 1 call to Exporter::import |
| 41 | 2 | 22µs | 2 | 54µs | # spent 30µs (7+23) within PPIx::Regexp::Element::BEGIN@41 which was called:
# once (7µs+23µs) by base::import at line 41 # spent 30µs making 1 call to PPIx::Regexp::Element::BEGIN@41
# spent 23µs making 1 call to Exporter::import |
| 42 | |||||
| 43 | 2 | 993µs | 2 | 882µs | # spent 840µs (322+517) within PPIx::Regexp::Element::BEGIN@43 which was called:
# once (322µs+517µs) by base::import at line 43 # spent 840µs making 1 call to PPIx::Regexp::Element::BEGIN@43
# spent 43µs making 1 call to Exporter::import |
| 44 | |||||
| 45 | 1 | 500ns | our $VERSION = '0.036'; | ||
| 46 | |||||
| 47 | =head2 ancestor_of | ||||
| 48 | |||||
| 49 | This method returns true if the object is an ancestor of the argument, | ||||
| 50 | and false otherwise. By the definition of this method, C<$self> is its | ||||
| 51 | own ancestor. | ||||
| 52 | |||||
| 53 | =cut | ||||
| 54 | |||||
| 55 | sub ancestor_of { | ||||
| 56 | my ( $self, $elem ) = @_; | ||||
| 57 | __instance( $elem, __PACKAGE__ ) or return; | ||||
| 58 | my $addr = refaddr( $self ); | ||||
| 59 | while ( $addr != refaddr( $elem ) ) { | ||||
| 60 | $elem = $elem->_parent() or return; | ||||
| 61 | } | ||||
| 62 | return 1; | ||||
| 63 | } | ||||
| 64 | |||||
| 65 | =head2 can_be_quantified | ||||
| 66 | |||||
| 67 | $token->can_be_quantified() | ||||
| 68 | and print "This element can be quantified.\n"; | ||||
| 69 | |||||
| 70 | This method returns true if the element can be quantified. | ||||
| 71 | |||||
| 72 | =cut | ||||
| 73 | |||||
| 74 | sub can_be_quantified { return 1; } | ||||
| 75 | |||||
| 76 | |||||
| 77 | =head2 class | ||||
| 78 | |||||
| 79 | This method returns the class name of the element. It is the same as | ||||
| 80 | C<ref $self>. | ||||
| 81 | |||||
| 82 | =cut | ||||
| 83 | |||||
| 84 | sub class { | ||||
| 85 | my ( $self ) = @_; | ||||
| 86 | return ref $self; | ||||
| 87 | } | ||||
| 88 | |||||
| 89 | =head2 comment | ||||
| 90 | |||||
| 91 | This method returns true if the element is a comment and false | ||||
| 92 | otherwise. | ||||
| 93 | |||||
| 94 | =cut | ||||
| 95 | |||||
| 96 | sub comment { | ||||
| 97 | return; | ||||
| 98 | } | ||||
| 99 | |||||
| 100 | =head2 content | ||||
| 101 | |||||
| 102 | This method returns the content of the element. | ||||
| 103 | |||||
| 104 | =cut | ||||
| 105 | |||||
| 106 | sub content { | ||||
| 107 | return; | ||||
| 108 | } | ||||
| 109 | |||||
| 110 | =head2 descendant_of | ||||
| 111 | |||||
| 112 | This method returns true if the object is a descendant of the argument, | ||||
| 113 | and false otherwise. By the definition of this method, C<$self> is its | ||||
| 114 | own descendant. | ||||
| 115 | |||||
| 116 | =cut | ||||
| 117 | |||||
| 118 | sub descendant_of { | ||||
| 119 | my ( $self, $node ) = @_; | ||||
| 120 | __instance( $node, __PACKAGE__ ) or return; | ||||
| 121 | return $node->ancestor_of( $self ); | ||||
| 122 | } | ||||
| 123 | |||||
| 124 | =head2 error | ||||
| 125 | |||||
| 126 | say $token->error(); | ||||
| 127 | |||||
| 128 | If an element is one of the classes that represents a parse error, this | ||||
| 129 | method B<may> return a brief message saying why. Otherwise it will | ||||
| 130 | return C<undef>. | ||||
| 131 | |||||
| 132 | =cut | ||||
| 133 | |||||
| 134 | sub error { | ||||
| 135 | my ( $self ) = @_; | ||||
| 136 | return $self->{error}; | ||||
| 137 | } | ||||
| 138 | |||||
| 139 | |||||
| 140 | =head2 is_quantifier | ||||
| 141 | |||||
| 142 | $token->is_quantifier() | ||||
| 143 | and print "This element is a quantifier.\n"; | ||||
| 144 | |||||
| 145 | This method returns true if the element is a quantifier. You can not | ||||
| 146 | tell this from the element's class, because a right curly bracket may | ||||
| 147 | represent a quantifier for the purposes of figuring out whether a | ||||
| 148 | greediness token is possible. | ||||
| 149 | |||||
| 150 | =cut | ||||
| 151 | |||||
| 152 | sub is_quantifier { return; } | ||||
| 153 | |||||
| 154 | =head2 modifier_asserted | ||||
| 155 | |||||
| 156 | $token->modifier_asserted( 'i' ) | ||||
| 157 | and print "Matched without regard to case.\n"; | ||||
| 158 | |||||
| 159 | This method returns true if the given modifier is in effect for the | ||||
| 160 | element, and false otherwise. | ||||
| 161 | |||||
| 162 | What it does is to walk backwards from the element until it finds a | ||||
| 163 | modifier object that specifies the modifier, whether asserted or | ||||
| 164 | negated. and returns the specified value. If nobody specifies the | ||||
| 165 | modifier, it returns C<undef>. | ||||
| 166 | |||||
| 167 | This method will not work reliably if called on tokenizer output. | ||||
| 168 | |||||
| 169 | =cut | ||||
| 170 | |||||
| 171 | sub modifier_asserted { | ||||
| 172 | my ( $self, $modifier ) = @_; | ||||
| 173 | |||||
| 174 | defined $modifier | ||||
| 175 | or croak 'Modifier must be defined'; | ||||
| 176 | |||||
| 177 | my $elem = $self; | ||||
| 178 | |||||
| 179 | while ( $elem ) { | ||||
| 180 | if ( $elem->can( '__ducktype_modifier_asserted' ) ) { | ||||
| 181 | my $val; | ||||
| 182 | defined( $val = $elem->__ducktype_modifier_asserted( $modifier ) ) | ||||
| 183 | and return $val; | ||||
| 184 | } | ||||
| 185 | if ( my $prev = $elem->sprevious_sibling() ) { | ||||
| 186 | $elem = $prev; | ||||
| 187 | } else { | ||||
| 188 | $elem = $elem->parent(); | ||||
| 189 | } | ||||
| 190 | } | ||||
| 191 | |||||
| 192 | return; | ||||
| 193 | } | ||||
| 194 | |||||
| 195 | =head2 next_sibling | ||||
| 196 | |||||
| 197 | This method returns the element's next sibling, or nothing if there is | ||||
| 198 | none. | ||||
| 199 | |||||
| 200 | =cut | ||||
| 201 | |||||
| 202 | sub next_sibling { | ||||
| 203 | my ( $self ) = @_; | ||||
| 204 | my ( $method, $inx ) = $self->_my_inx() | ||||
| 205 | or return; | ||||
| 206 | return $self->_parent()->$method( $inx + 1 ); | ||||
| 207 | } | ||||
| 208 | |||||
| 209 | =head2 parent | ||||
| 210 | |||||
| 211 | This method returns the parent of the element, or undef if there is | ||||
| 212 | none. | ||||
| 213 | |||||
| 214 | =cut | ||||
| 215 | |||||
| 216 | sub parent { | ||||
| 217 | my ( $self ) = @_; | ||||
| 218 | return $self->_parent(); | ||||
| 219 | } | ||||
| 220 | |||||
| 221 | =head2 perl_version_introduced | ||||
| 222 | |||||
| 223 | This method returns the version of Perl in which the element was | ||||
| 224 | introduced. This will be at least 5.000. Before 5.006 I am relying on | ||||
| 225 | the F<perldelta>, F<perlre>, and F<perlop> documentation, since I have | ||||
| 226 | been unable to build earlier Perls. Since I have found no documentation | ||||
| 227 | before 5.003, I assume that anything found in 5.003 is also in 5.000. | ||||
| 228 | |||||
| 229 | Since this all depends on my ability to read and understand masses of | ||||
| 230 | documentation, the results of this method should be viewed with caution, | ||||
| 231 | if not downright skepticism. | ||||
| 232 | |||||
| 233 | There are also cases which are ambiguous in various ways. For those see | ||||
| 234 | L<PPIx::Regexp/RESTRICTIONS>, and especially | ||||
| 235 | L<PPIx::Regexp/Changes in Syntax>. | ||||
| 236 | |||||
| 237 | =cut | ||||
| 238 | |||||
| 239 | sub perl_version_introduced { | ||||
| 240 | return MINIMUM_PERL; | ||||
| 241 | } | ||||
| 242 | |||||
| 243 | =head2 perl_version_removed | ||||
| 244 | |||||
| 245 | This method returns the version of Perl in which the element was | ||||
| 246 | removed. If the element is still valid the return is C<undef>. | ||||
| 247 | |||||
| 248 | All the I<caveats> to | ||||
| 249 | L<perl_version_introduced()|/perl_version_introduced> apply here also, | ||||
| 250 | though perhaps less severely since although many features have been | ||||
| 251 | introduced since 5.0, few have been removed. | ||||
| 252 | |||||
| 253 | =cut | ||||
| 254 | |||||
| 255 | sub perl_version_removed { | ||||
| 256 | return undef; ## no critic (ProhibitExplicitReturnUndef) | ||||
| 257 | } | ||||
| 258 | |||||
| 259 | =head2 previous_sibling | ||||
| 260 | |||||
| 261 | This method returns the element's previous sibling, or nothing if there | ||||
| 262 | is none. | ||||
| 263 | |||||
| 264 | =cut | ||||
| 265 | |||||
| 266 | sub previous_sibling { | ||||
| 267 | my ( $self ) = @_; | ||||
| 268 | my ( $method, $inx ) = $self->_my_inx() | ||||
| 269 | or return; | ||||
| 270 | $inx or return; | ||||
| 271 | return $self->_parent()->$method( $inx - 1 ); | ||||
| 272 | } | ||||
| 273 | |||||
| 274 | =head2 significant | ||||
| 275 | |||||
| 276 | This method returns true if the element is significant and false | ||||
| 277 | otherwise. | ||||
| 278 | |||||
| 279 | =cut | ||||
| 280 | |||||
| 281 | sub significant { | ||||
| 282 | return 1; | ||||
| 283 | } | ||||
| 284 | |||||
| 285 | =head2 snext_sibling | ||||
| 286 | |||||
| 287 | This method returns the element's next significant sibling, or nothing | ||||
| 288 | if there is none. | ||||
| 289 | |||||
| 290 | =cut | ||||
| 291 | |||||
| 292 | sub snext_sibling { | ||||
| 293 | my ( $self ) = @_; | ||||
| 294 | my $sib = $self; | ||||
| 295 | while ( defined ( $sib = $sib->next_sibling() ) ) { | ||||
| 296 | $sib->significant() and return $sib; | ||||
| 297 | } | ||||
| 298 | return; | ||||
| 299 | } | ||||
| 300 | |||||
| 301 | =head2 sprevious_sibling | ||||
| 302 | |||||
| 303 | This method returns the element's previous significant sibling, or | ||||
| 304 | nothing if there is none. | ||||
| 305 | |||||
| 306 | =cut | ||||
| 307 | |||||
| 308 | sub sprevious_sibling { | ||||
| 309 | my ( $self ) = @_; | ||||
| 310 | my $sib = $self; | ||||
| 311 | while ( defined ( $sib = $sib->previous_sibling() ) ) { | ||||
| 312 | $sib->significant() and return $sib; | ||||
| 313 | } | ||||
| 314 | return; | ||||
| 315 | } | ||||
| 316 | |||||
| 317 | =head2 tokens | ||||
| 318 | |||||
| 319 | This method returns all tokens contained in the element. | ||||
| 320 | |||||
| 321 | =cut | ||||
| 322 | |||||
| 323 | sub tokens { | ||||
| 324 | my ( $self ) = @_; | ||||
| 325 | return $self; | ||||
| 326 | } | ||||
| 327 | |||||
| 328 | =head2 top | ||||
| 329 | |||||
| 330 | This method returns the top of the hierarchy. | ||||
| 331 | |||||
| 332 | =cut | ||||
| 333 | |||||
| 334 | sub top { | ||||
| 335 | my ( $self ) = @_; | ||||
| 336 | my $kid = $self; | ||||
| 337 | while ( defined ( my $parent = $kid->_parent() ) ) { | ||||
| 338 | $kid = $parent; | ||||
| 339 | } | ||||
| 340 | return $kid; | ||||
| 341 | } | ||||
| 342 | |||||
| 343 | =head2 unescaped_content | ||||
| 344 | |||||
| 345 | This method returns the content of the element, unescaped. | ||||
| 346 | |||||
| 347 | =cut | ||||
| 348 | |||||
| 349 | sub unescaped_content { | ||||
| 350 | return; | ||||
| 351 | } | ||||
| 352 | |||||
| 353 | =head2 whitespace | ||||
| 354 | |||||
| 355 | This method returns true if the element is whitespace and false | ||||
| 356 | otherwise. | ||||
| 357 | |||||
| 358 | =cut | ||||
| 359 | |||||
| 360 | sub whitespace { | ||||
| 361 | return; | ||||
| 362 | } | ||||
| 363 | |||||
| 364 | =head2 nav | ||||
| 365 | |||||
| 366 | This method returns navigation information from the top of the hierarchy | ||||
| 367 | to this node. The return is a list of names of methods and references to | ||||
| 368 | their argument lists. The idea is that given C<$elem> which is somewhere | ||||
| 369 | under C<$top>, | ||||
| 370 | |||||
| 371 | my @nav = $elem->nav(); | ||||
| 372 | my $obj = $top; | ||||
| 373 | while ( @nav ) { | ||||
| 374 | my $method = shift @nav; | ||||
| 375 | my $args = shift @nav; | ||||
| 376 | $obj = $obj->$method( @{ $args } ) or die; | ||||
| 377 | } | ||||
| 378 | # At this point, $obj should contain the same object | ||||
| 379 | # as $elem. | ||||
| 380 | |||||
| 381 | =cut | ||||
| 382 | |||||
| 383 | sub nav { | ||||
| 384 | my ( $self ) = @_; | ||||
| 385 | __instance( $self, __PACKAGE__ ) or return; | ||||
| 386 | |||||
| 387 | # We do not use $self->parent() here because PPIx::Regexp overrides | ||||
| 388 | # this to return the (possibly) PPI object that initiated us. | ||||
| 389 | my $parent = $self->_parent() or return; | ||||
| 390 | |||||
| 391 | return ( $parent->nav(), $parent->_nav( $self ) ); | ||||
| 392 | } | ||||
| 393 | |||||
| 394 | # Find our location and index among the parent's children. If not found, | ||||
| 395 | # just returns. | ||||
| 396 | |||||
| 397 | { | ||||
| 398 | 2 | 2µs | my %method_map = ( | ||
| 399 | children => 'child', | ||||
| 400 | ); | ||||
| 401 | sub _my_inx { | ||||
| 402 | my ( $self ) = @_; | ||||
| 403 | my $parent = $self->_parent() or return; | ||||
| 404 | my $addr = refaddr( $self ); | ||||
| 405 | foreach my $method ( qw{ children start type finish } ) { | ||||
| 406 | $parent->can( $method ) or next; | ||||
| 407 | my $inx = firstidx { refaddr $_ == $addr } $parent->$method(); | ||||
| 408 | $inx < 0 and next; | ||||
| 409 | return ( $method_map{$method} || $method, $inx ); | ||||
| 410 | } | ||||
| 411 | return; | ||||
| 412 | } | ||||
| 413 | } | ||||
| 414 | |||||
| 415 | { | ||||
| 416 | 2 | 300ns | my %parent; | ||
| 417 | |||||
| 418 | # no-argument form returns the parent; one-argument sets it. | ||||
| 419 | sub _parent { | ||||
| 420 | my ( $self, @arg ) = @_; | ||||
| 421 | my $addr = refaddr( $self ); | ||||
| 422 | if ( @arg ) { | ||||
| 423 | my $parent = shift @arg; | ||||
| 424 | if ( defined $parent ) { | ||||
| 425 | __instance( $parent, __PACKAGE__ ) or return; | ||||
| 426 | weaken( | ||||
| 427 | $parent{$addr} = $parent ); | ||||
| 428 | } else { | ||||
| 429 | delete $parent{$addr}; | ||||
| 430 | } | ||||
| 431 | } | ||||
| 432 | return $parent{$addr}; | ||||
| 433 | } | ||||
| 434 | |||||
| 435 | sub _parent_keys { | ||||
| 436 | return scalar keys %parent; | ||||
| 437 | } | ||||
| 438 | |||||
| 439 | } | ||||
| 440 | |||||
| 441 | # $self->__impose_defaults( $arg, \%default ); | ||||
| 442 | # | ||||
| 443 | # This method can be called in __PPIX_TOKEN__post_make() to supply | ||||
| 444 | # defaults for attributes. It returns nothing. | ||||
| 445 | # | ||||
| 446 | # The arguments are hash references, which are taken in left-to-right | ||||
| 447 | # order, with the, with the first extant value being used. | ||||
| 448 | |||||
| 449 | sub __impose_defaults { | ||||
| 450 | my ( $self, @args ) = @_; | ||||
| 451 | foreach my $arg ( @args ) { | ||||
| 452 | ref $arg eq 'HASH' | ||||
| 453 | or next; | ||||
| 454 | foreach my $key ( keys %{ $arg } ) { | ||||
| 455 | exists $self->{$key} | ||||
| 456 | or $self->{$key} = $arg->{$key}; | ||||
| 457 | } | ||||
| 458 | } | ||||
| 459 | return; | ||||
| 460 | } | ||||
| 461 | |||||
| 462 | # Bless into TOKEN_UNKNOWN, record error message, return 1. | ||||
| 463 | sub __error { | ||||
| 464 | my ( $self, $msg ) = @_; | ||||
| 465 | $self->isa( 'PPIx::Token::Node' ) | ||||
| 466 | and confess 'Programming error - __error() must be overridden', | ||||
| 467 | ' for class ', ref $self; | ||||
| 468 | defined $msg | ||||
| 469 | or $msg = 'Was ' . ref $self; | ||||
| 470 | $self->{error} = $msg; | ||||
| 471 | bless $self, TOKEN_UNKNOWN; | ||||
| 472 | return 1; | ||||
| 473 | } | ||||
| 474 | |||||
| 475 | # Called by the lexer to record the capture number. | ||||
| 476 | sub __PPIX_LEXER__record_capture_number { | ||||
| 477 | my ( $self, $number ) = @_; | ||||
| 478 | return $number; | ||||
| 479 | } | ||||
| 480 | |||||
| 481 | sub DESTROY { | ||||
| 482 | $_[0]->_parent( undef ); | ||||
| 483 | return; | ||||
| 484 | } | ||||
| 485 | |||||
| 486 | 1 | 3µs | 1; | ||
| 487 | |||||
| 488 | __END__ |