Blame inc/latest/private.pm

Packit bc8539
use strict;
Packit bc8539
use warnings;
Packit bc8539
Packit bc8539
package inc::latest::private;
Packit bc8539
# ABSTRACT: private implementation for inc::latest
Packit bc8539
Packit bc8539
our $VERSION = '0.500';
Packit bc8539
Packit bc8539
use File::Spec;
Packit bc8539
use IO::File;
Packit bc8539
Packit bc8539
# must ultimately "goto" the import routine of the module to be loaded
Packit bc8539
# so that the calling package is correct when $mod->import() runs.
Packit bc8539
sub import {
Packit bc8539
    my ( $package, $mod, @args ) = @_;
Packit bc8539
    my $file = $package->_mod2path($mod);
Packit bc8539
Packit bc8539
    if ( $INC{$file} ) {
Packit bc8539
        # Already loaded, but let _load_module handle import args
Packit bc8539
        goto \&_load_module;
Packit bc8539
    }
Packit bc8539
Packit bc8539
    # A bundled copy must be present
Packit bc8539
    my ( $bundled, $bundled_dir ) = $package->_search_bundled($file)
Packit bc8539
      or die "No bundled copy of $mod found";
Packit bc8539
Packit bc8539
    my $from_inc = $package->_search_INC($file);
Packit bc8539
    unless ($from_inc) {
Packit bc8539
        # Only bundled is available
Packit bc8539
        unshift( @INC, $bundled_dir );
Packit bc8539
        goto \&_load_module;
Packit bc8539
    }
Packit bc8539
Packit bc8539
    if ( _version($from_inc) >= _version($bundled) ) {
Packit bc8539
        # Ignore the bundled copy
Packit bc8539
        goto \&_load_module;
Packit bc8539
    }
Packit bc8539
Packit bc8539
    # Load the bundled copy
Packit bc8539
    unshift( @INC, $bundled_dir );
Packit bc8539
    goto \&_load_module;
Packit bc8539
}
Packit bc8539
Packit bc8539
sub _version {
Packit bc8539
    require ExtUtils::MakeMaker;
Packit bc8539
    return ExtUtils::MM->parse_version(shift);
Packit bc8539
}
Packit bc8539
Packit bc8539
# use "goto" for import to preserve caller
Packit bc8539
sub _load_module {
Packit bc8539
    my $package = shift; # remaining @_ is ready for goto
Packit bc8539
    my ( $mod, @args ) = @_;
Packit bc8539
    eval "require $mod; 1" or die $@;
Packit bc8539
    if ( my $import = $mod->can('import') ) {
Packit bc8539
        goto $import;
Packit bc8539
    }
Packit bc8539
    return 1;
Packit bc8539
}
Packit bc8539
Packit bc8539
sub _search_bundled {
Packit bc8539
    my ( $self, $file ) = @_;
Packit bc8539
Packit bc8539
    my $mypath = 'inc';
Packit bc8539
Packit bc8539
    local *DH; # Maintain 5.005 compatibility
Packit bc8539
    opendir DH, $mypath or die "Can't open directory $mypath: $!";
Packit bc8539
Packit bc8539
    while ( defined( my $e = readdir DH ) ) {
Packit bc8539
        next unless $e =~ /^inc_/;
Packit bc8539
        my $try = File::Spec->catfile( $mypath, $e, $file );
Packit bc8539
Packit bc8539
        return ( $try, File::Spec->catdir( $mypath, $e ) ) if -e $try;
Packit bc8539
    }
Packit bc8539
    return;
Packit bc8539
}
Packit bc8539
Packit bc8539
# Look for the given path in @INC.
Packit bc8539
sub _search_INC {
Packit bc8539
    # TODO: doesn't handle coderefs or arrayrefs or objects in @INC, but
Packit bc8539
    # it probably should
Packit bc8539
    my ( $self, $file ) = @_;
Packit bc8539
Packit bc8539
    foreach my $dir (@INC) {
Packit bc8539
        next if ref $dir;
Packit bc8539
        my $try = File::Spec->catfile( $dir, $file );
Packit bc8539
        return $try if -e $try;
Packit bc8539
    }
Packit bc8539
Packit bc8539
    return;
Packit bc8539
}
Packit bc8539
Packit bc8539
# Translate a module name into a directory/file.pm to search for in @INC
Packit bc8539
sub _mod2path {
Packit bc8539
    my ( $self, $mod ) = @_;
Packit bc8539
    my @parts = split /::/, $mod;
Packit bc8539
    $parts[-1] .= '.pm';
Packit bc8539
    return $parts[0] if @parts == 1;
Packit bc8539
    return File::Spec->catfile(@parts);
Packit bc8539
}
Packit bc8539
Packit bc8539
1;
Packit bc8539
Packit bc8539
Packit bc8539
# vim: ts=4 sts=4 sw=4 tw=75 et:
Packit bc8539
Packit bc8539
__END__
Packit bc8539
Packit bc8539
=pod
Packit bc8539
Packit bc8539
=encoding UTF-8
Packit bc8539
Packit bc8539
=head1 NAME
Packit bc8539
Packit bc8539
inc::latest::private - private implementation for inc::latest
Packit bc8539
Packit bc8539
=head1 VERSION
Packit bc8539
Packit bc8539
version 0.500
Packit bc8539
Packit bc8539
=head1 DESCRIPTION
Packit bc8539
Packit bc8539
This module has the private methods used to find and load bundled modules.
Packit bc8539
It should not be used directly.
Packit bc8539
Packit bc8539
=head1 AUTHORS
Packit bc8539
Packit bc8539
=over 4
Packit bc8539
Packit bc8539
=item *
Packit bc8539
Packit bc8539
David Golden <dagolden@cpan.org>
Packit bc8539
Packit bc8539
=item *
Packit bc8539
Packit bc8539
Eric Wilhelm <ewilhelm@cpan.org>
Packit bc8539
Packit bc8539
=back
Packit bc8539
Packit bc8539
=head1 COPYRIGHT AND LICENSE
Packit bc8539
Packit bc8539
This software is Copyright (c) 2009 by David Golden.
Packit bc8539
Packit bc8539
This is free software, licensed under:
Packit bc8539
Packit bc8539
  The Apache License, Version 2.0, January 2004
Packit bc8539
Packit bc8539
=cut