NAME

Devel::Hook::INC - Hook into loading and unloading Perl library files.

SYNOPSIS

    unshift @INC, My::INC->new;

    package My::INC;

    use strict;
    use warnings;

    use base qw( Devel::Hook::INC );

    sub before
    {
        my( $self, $S ) = @_;
        warn "Loading $S->{filename}";
    }    

    sub after
    {
        my( $self, $S ) = @_;
        warn "Loaded $S->{filename}";
    }

DESCRIPTION

Devel::Hook::INC implements hooks that are called before and after a library file is loaded with "require" in perlfunc or "use" in perlfunc. It is intended for versions of Perl that don't have "%{^HOOK}" in perlvar.

The perl interpreter includes a library file, it looks through a list of places in @INC where the file might be stored. While this is would easily allow us to know when the interpreter starts reading a file, knowing when the interpreter stopped reading a file is harder.

Devel::Hook::INC works by also scanning each line of the library file when it is read. POD is removed and replaced by a #line directive. The perl interpreter stops reading when it sees __END__ and __DATA__, so Devel::Hook::INC counts those as EOF.

Devel::Hook::INC was written to discover modules that were very slow to load. The goal was to then load those modules only when needed.

OVERLOAD

new

    push @INC, My::INC->new;

Create the object that will be put into @INC. No parameters.

before

    sub before 
    {
        my( $self, $S ) = @_;
        print "Loading $S->{filename}\n";
    }

Called before each library file is read and parsed by the perl interpreter. $S is the "LOADING CONTEXT".

after

    sub after
    {
        my( $self, $S ) = @_;
        print "Loaded $S->{filename}\n";
    }

Called after each library file is read but before the perl interpreter finishes parsing it. $S is the "LOADING CONTEXT".

LOADING CONTEXT

The "before" and "after" methods are called with a single parameter: a loading context. This context is a hashref with the following keys.

filename

Filename of the library file. This is the string passed to require or, in the case of use, the module name is converted to a filename - .pm appended and :: is replaced with the directory seperator (/). Note that this transformation is done by the perl interpreter itself.

file

Fully qualified filename of the library file being loaded. This is "filename" prefixed with the first relevant directory from @INC.

line

Current line number.

caller

Arrayref containing the location the package was first included from. See "caller" in perlfunc.

fh

The filehandle of the package being loaded. Note that this might be at EOF during "after".

METHODS

The following is a full list of the methods implmented by Devel::Hook::INC. It is intended for advanced use. The API might change. For more details on these methods, read Devel::Hook::INC's source code.

Devel::Hook::INC::INC

Called by the perl interpreter when a library file is to be loaded. For some undocumented reason the full package name is required.

__before

Builds and returns the loading context. Adds it to the stack.

__after

Removes the current loading context from the stack.

__caller

Returns the perl calling context a library file was loaded from. Uses "__reject" to make sure the calling context is relevant. See "caller" in perlfunc.

__reject

The calls using @INC hooks tend to be obsucred by Perl - that is, they are wrapped in eval{} or __ANON__ subs. This method is used to filter out those calling contexts and only use relevant ones.

Returns true if this calling context isn't relevant and we should look futher up the stack. Returns false if we should use this calling context.

open

Opens the file to be parsed and returns a file handle.

hash_line

Returns the #line directive that is then passed to the Perl interpreter. Used to skip over POD. See "Plain-Old-Comments-(Not!)" in perlsyn

printline

Debug function.

stack

Returns the current loading context.

depth

Current depth of includes.

line

Read one line of the package being loaded. Skips over POD. Detects the end of a file and __END__ or __DATA__. This is called by perl interpreter.

readline

Read and return one line of the library file.

SEE ALSO

AUTHOR

Philip Gwyn, <gwyn -AT- cpan.org >

COPYRIGHT AND LICENSE

Copyright (C) 2023 by Philip Gwyn

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.26.3 or, at your option, any later version of Perl 5 you may have available.