package PPI::XS; # See POD at end for documentation use 5.005; use strict; use XSLoader; # In the unlikely case they someone tries to manually load # PPI::XS without PPI itself loaded, they probably MEAN for us # to load in PPI as well. Pretty useless otherwise, because we # need to _overwrite_ the PPI methods, we can't have it loading # after we do. use PPI 1.000 (); # Define compatibility information use vars qw{$VERSION $PM_COMPATIBLE %EXCLUDE}; BEGIN { $VERSION = '0.901'; $PM_COMPATIBLE = '0.844'; %EXCLUDE = (); } # Does the main package define the minimum set of variables? return 1 unless defined $PPI::VERSION; return 1 unless defined $PPI::XS_COMPATIBLE; return 1 if $PPI::VERSION =~ /_/; # Are we compatible with the main package return 1 unless $VERSION > $PPI::XS_COMPATIBLE; return 1 unless $PPI::VERSION > $PM_COMPATIBLE; # Provide an option to manually disable this package return 1 if $PPI::XS_DISABLE; # If we aren't EXACTLY the same version, determine # which functions we might need to exclude. if ( $VERSION > $PPI::VERSION ) { # We are newer, we have the option of excluding functions ### NOTE: Nothing to exclude in this version # %EXCLUDE = map { $_ => 1 } qw{}; # (example) PPI::Element::exclude_this } elsif ( $VERSION < $PPI::VERSION ) { # It is newer, it has the option of excluding functions if ( defined @PPI::XS_EXCLUDE ) { # It as defined things for us to exclude %EXCLUDE = map { $_ => 1 } @PPI::XS_EXCLUDE; } } # Load the XS functions XSLoader::load( 'PPI::XS' => $VERSION ); # Find all the functions in PPI::XS no strict 'refs'; foreach ( sort grep { /^_PPI_/ and defined &{"PPI::XS::$_"} } keys %{"PPI::XS::"} ) { # Prepare /^_(\w+?)__(\w+)$/ or next; my ($class, $function) = ($1, $2); $class =~ s/_/::/g; if ( $EXCLUDE{$_} ) { # Remove the un-needed function. # The primary purpose of this is to recover the memory # occupied by the useless functions, but has the # additional benefit of allowing us to detect which # functions were actually mapped in by examining the # names of the functions remaining in the PPI::XS symbol # table. delete ${"PPI::XS::"}{$_}; } else { # Map in the function *{"${class}::${function}"} = *{"PPI::XS::$_"}; } } 1; __END__ =pod =head1 NAME PPI::XS - (Minor) XS acceleration for PPI =head1 DESCRIPTION PPI::XS provides XS-based acceleration of the core PPI packages. It selectively replaces a (small but growing) number of methods throughout PPI with identical but much faster C versions. Once installed, it will be auto-detected and loaded in by PPI completely transparently. Because the C implementations are linked to the perl versions of the same function, it is preferable to upgrade PPI::XS any time you do a major upgrade of PPI itself. If the two fall out of sync, the integration between the two is designed to degrade gracefully. PPI::XS is capable of determining which functions are no longer equal, and will simple leave the perl version alone, deleting the C version to free up the memory. If the versions of the two get so far apart that they become completely incompatible, PPI::XS will simply silently not load at all. Beyond that, there isn't that much more you really need to know. :) =head1 SUPPORT Bugs should always be submitted via the CPAN bug tracker, located at L For other issues or comments, contact the maintainer. =head1 AUTHOR Adam Kennedy Eadamk@cpan.orgE =head1 SEE ALSO L =head1 COPYRIGHT Copyright 2005 - 2009 Adam Kennedy. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. The full text of the license can be found in the LICENSE file included with this module. =cut