develooper Front page | perl.perl5.porters | Postings from August 2001

[DOC PATCH] The coderef-in-@INC feature

Thread Next
Rafael Garcia-Suarez
August 24, 2001 14:31
[DOC PATCH] The coderef-in-@INC feature
Message ID:
Here's a first attempt at documenting the coderef-in-@INC feature.

I've not documented all features actually implemented (there is no
description for the way to put also hooks into the tokenizer's source
filters). (If someone has used somewhere in the core or on CPAN this
feature, let me know.)

While testing this feature I've found some bugs and some strange behavior:

1. blessed arrays in @INC don't work, while blessed scalars and hashes do.

2. %INC contains, for a module loaded via a hook in @INC, something like
"/loader/0x8118fb0/Foo/" ; but I can't figure out yet what the
address is. (This probably needs to be documented).

3. See this program :
	package Foo;
	push @INC, [ 'fooinc' ]; # This is @main::INC
	package Bar;
	require Quux;
It fails with "Undefined subroutine &Bar::fooinc called at..."
A funny variant of polymorphism !

The doc patch :

--- perlvar.pod.orig	Thu Aug 23 22:28:59 2001
+++ perlvar.pod	Fri Aug 24 21:24:54 2001
@@ -1062,6 +1062,10 @@
     use lib '/mypath/libdir/';
     use SomeMod;
+You can also insert hooks into the file inclusion system by putting Perl
+code directly into @INC.  Those hooks may be subroutine references, array
+references or blessed objects.  See L<perlfunc/require> for details.
 =item @_
 Within a subroutine the array @_ contains the parameters passed to that
--- perlfunc.pod.orig	Fri Aug 24 21:27:25 2001
+++ perlfunc.pod	Fri Aug 24 23:15:18 2001
@@ -3808,6 +3808,57 @@
         eval "require $class";
+You can also insert hooks into the import facility, by putting directly
+Perl code into the @INC array.  There are three forms of hooks: subroutine
+references, array references and blessed objects.
+Subroutine references are the simplest case.  When the inclusion system
+walks through @INC and encounters a subroutine, this subroutine gets
+called with two parameters, the first being a reference to itself, and the
+second the name of the file to be included (e.g. "F<Foo/>").  The
+subroutine should return C<undef> or a filehandle, from which the file to
+include will be read.  If C<undef> is returned, C<require> will look at
+the remaining elements of @INC.
+If the hook is an array reference, its first element must be a subroutine
+reference.  This subroutine is called as above, but the first parameter is
+the array reference.  This enables to pass indirectly some arguments to
+the subroutine.
+In other words, you can write:
+    push @INC, \&my_sub;
+    sub my_sub {
+	my ($coderef, $filename) = @_;	# $coderef is \&my_sub
+	...
+    }
+    push @INC, [ \&my_sub, $x, $y, ... ];
+    sub my_sub {
+	my ($arrayref, $filename) = @_;
+	# Retrieve $x, $y, ...
+	my @parameters = @$arrayref[1..$#$arrayref];
+	...
+    }
+If the hook is an object, it must provide an INC method, that will be
+called as above, the first parameter being the object itself.  (Note that
+you must fully qualify the sub's name, as it is always forced into package
+C<main>.)  Here is a typical code layout:
+    # In
+    package Foo;
+    sub new { ... }
+    sub Foo::INC {
+	my ($self, $filename) = @_;
+	...
+    }
+    # In the main program
+    push @INC, new Foo(...);
 For a yet-more-powerful import facility, see L</use> and L<perlmod>.
 =item reset EXPR

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About