
use strict;
use warnings;

package file v0.20.007;
# ABSTRACT: Perl module to load files at compile-time, without BEGIN blocks.


use Carp ();


# Modified version of the code as specified in `perldoc -f require`
*import = \&require;
sub require {
    shift;    # Class
    my $filename = @_ ? shift : $_;
    Carp::croak("Null filename used") unless length($filename);
    if (exists $INC{$filename}) {
        return 1 if $INC{$filename};
        return;
    }
    my $result;
    ITER: {
        if ( $filename =~ m!\A/! ) {
            $result = do $filename;
            last ITER;
        }
        foreach my $prefix (@INC) {
            next unless -f ( my $fullpath = "$prefix/$filename" );
            $result = do $fullpath;
            $INC{$filename} = delete $INC{$fullpath};
            last ITER;
        }
        Carp::croak("Can't locate $filename in \@INC (\@INC contains: @INC)");
    }
    if ($result) {
        return $result;
    } elsif ($@) {
        $INC{$filename} = undef;
        Carp::croak( $@, "Compilation failed in require" );
    } elsif ($!) {
        $INC{$filename} = undef;
        Carp::croak("Can't locate $filename:   $!");
    } else {
        delete $INC{$filename};
        Carp::croak("$filename did not return a true value");
    }
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

file - Perl module to load files at compile-time, without BEGIN blocks.

=head1 SYNOPSIS

    # Instead of "BEGIN { require '/path/to/file.pm' }"
    # use the more succinct:
    use file '/path/to/file.pm';

    # Or, if you need to do include a file relative to the program:
    use FindBin qw($Bin);
    use file "$Bin/../lib/Application.pm";

    # Do it at runtime:
    file->require('/path/to/file.pm');

    # Throw it into a loop:
    say( 'Required: ', $_ ) foreach grep file->require, @files;

=head1 DESCRIPTION

This module came about because there was a need to include some standard
boilerplate that included some configuration and application specific paths
to all modules for an application, and to do it at compile time.
Rather than repeating C<BEGIN { require ... }> in every single entry point
for the application, this module was created to simplify the experience.

The intention is to have this module be equivalent to L<perlfunc/require>,
except that it's run at compile time (via L<perlfunc/use>),
rather than at runtime.

=head1 METHODS

=head2 C<require( $filename = $_ )>

Does the equivalent of L<perlfunc/require> on the supplied C<$filename>,
or C<$_> if no argument is provided.

Must be called as a class method: C<< file->require( $filename ) >>

=head1 BUGS

Please report any bugs or feature requests on the bugtracker website
L<https://github.com/rkleemann/file/issues>

When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.

=head1 VERSION

This document describes version v0.20.007 of this module.

=head1 AUTHOR

Bob Kleemann <bobk@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is Copyright (c) 2019 by Bob Kleemann.

This is free software, licensed under:

  The Artistic License 2.0 (GPL Compatible)

=cut
