NAME
    Path::ScanINC - Emulate Perls internal handling of @INC.

VERSION
    version 0.001

SYNOPSIS
    The Aim of this module is to fully implement everything Perl does with
    @INC, to be feature compatible with it, including the behaviour with
    regard to "sub refs" in @INC.

            use Path::ScanINC;

            # Normal usage.
            my $inc = Path::ScanINC->new( );

            # In case you need something that isn't @INC
            # but works like it

            my $inc = Path::ScanINC->new( inc => \@INC );

            # Freeze the value of @INC at the time of object instantiation
            # with regard to behaviour so later changes to @INC have no effect

            my $inc = Path::ScanINC->new( immutable => 1 );

            # Return the first file in @INC that matches.

            my $file = $inc->first_file('Path', 'ScanINC.pm' );

            # Find all possible versions of modules in @INC
            my ( @files ) = $inc->all_files('Path', 'ScanINC.pm');

            # Try to discover a File::ShareDir 'module' root.
            my $dir = $inc->first_dir('auto','share','module');

            # Should return the same as File::ShareDir::module_dir('Path::ScanINC')
            # ( assuming such a directory existed, which there is presently no plans of )
            my $dir = $inc->first_dir('auto','share','module','Path-ScanINC');


            # Find All File::ShareDir roots in @INC
            my ( @dirs ) = $inc->all_dirs('auto', 'share');

REF SUPPORT IN @INC
    This module has elemental support for discovery of results in @INC using
    "CODE"/"ARRAY"/"BLESSED" entries in @INC. However, due to a limitation
    as to how perl itself implements this functionality, the best we can do
    at present is simply return what the above are expected to return. This
    means if you have any of the above ref-types in @INC, and one of those
    returns "a true value", you'll get handed back an "ARRAY" reference
    instead of the file you were expecting.

    Fortunately, @INC barely ever has refs in it. But in the event you
    *need* to work with refs in @INC and you expect that those refs will
    return "true", you have to pick one of two options, either :

    a. Write your code to work with the "array-ref" returned by the
    respective reference on a match
    b. Use the "all_" family of methods and try pretendeding that there are
    no "array-refs" in the list it returns.

    Its possible in a future release we may have better choices how to
    handle this situation in future, but don't bet on it.

    Given that the API as defined by Perl mandates "code-ref"'s return lists
    containing "file-handles" or iterative "code-ref"'s , not actual files,
    the best I can forsee at this time we'd be able to do to make life
    easier for you is creating a fake library somewhere in a "tempdir" and
    stuffing the result of the "code-ref"'s into files in that dir prior to
    returning a path to the generated file.

    ( And it also tells me that they have to be "Real" file handles, not
    tied or blessed ones, so being able to ask a filehandle what file it
    represents is equally slim.... if that is of course what you require )

    For more details, see "perldoc perlfunc" or "perldoc -f require" .

METHODS
  new
            my $object = $class->new(
                     inc => [ 'x', 'y', 'z' , ],
                     immutable => 1 | undef
            );

  immutable
            if( $inc->immutable ) {
                    print "We're working with a snapshotted version of @INC";
            }

  inc
            for my $i ( $inc->inc ) {
                    say "Plain: $incer" if not ref $incer;
                    say "Callback: $incer" if ref $incer;
            }

    Returns a copy of the internal version of @INC it will be using.

    If the object is "immutable", then this method will continue to report
    the same value as c<@INC>, or will be updated every time the orignal
    array reference passed during construction gets updated:

            my $ref = [];
            my $a = Path::ScanINC->new( inc => $inc );
            my $b = Path::ScanINC->new( inc => $inc, immutable => 1 );

            push @{$ref} , 'a';

            is( [ $a->inc ]->[0] , 'a' , "non-immutable references keep tracking their original" );
            isnt( [ $a->inc ]->[0] , 'a' , "immutable references are shallow-copied at construction" );

    Do note of course that is a SHALLOW copy, so if you have multiple @INC
    copies sharing the same "array"/"bless" references, changes to those
    references will be shared amongst all @INC's .

  first_file
            if( defined ( my $file = $inc->first_file('Moose.pm') ) {
                    print "Yep, Moose seems to be available in \@INC , its at $file, but its not loaded (yet)\n";
            }

    This proves to be a handy little gem that replaces the oft used

            if( try { require Moose ; 1 } ){
                    Yadayadayada
            }

    And adds the benefit of not needing to actually source the file to see
    if it exists or not.

  all_files
    Returns all matches in all @INC paths.

            my $inc = Path::ScanINC->new();
            push @INC, 'lib';
            my ( @files ) = $inc->all_files('Something','Im','Working','On.pm');
            pp(\@files );

            # [
            #    '/something/........./lib/Something/Im/Working/On.pm',
            #    '/something/....../share/per5/lib/site_perl/5.15.9/Something/Im/Working/On.pm',
            # ]

    Chances are if you understand how this can be useful, you'll do so
    immediately.

    Useful for debugging what module is being loaded, and possibly
    introspecting information about multiple parallel installs of modules in
    %ENV, such as frequently the case with 'dual-life' modules.

            perl -MPath::ScanINC -E 'my $scanner = Path::ScanINC->new(); say for $scanner->all_files(qw( Scalar Util.pm ))'
            /usr/lib64/perl5/vendor_perl/5.12.4/x86_64-linux/Scalar/Util.pm
            /usr/lib64/perl5/5.12.4/x86_64-linux/Scalar/Util.pm

    Sort-of like ye' olde' "perldoc -l", but more like "man -a"

    I might even be tempted to make a sub-module to make one-liners easier
    like

            perl -MPath::ScanINC::All=Scalar/Util.pm

    REMINDER: If there are "REFS" in @INC that match, they'll return
    "array-ref"'s, not strings.

  first_dir
    Just like "first_file" except for locating directories.

  all_dirs
    Just like "all_dirs" except for locating directories.

AUTHOR
    Kent Fredric <kentnl@cpan.org>

COPYRIGHT AND LICENSE
    This software is copyright (c) 2012 by Kent Fredric <kentnl@cpan.org>.

    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.

