In perl.git, the branch ap/baseincguard has been updated <http://perl5.git.perl.org/perl.git/commitdiff/9404d5cea31a76376f4d45b697749cbf9b7f7448?hp=bcafe078ba2cf05417851462cd4506e758839b29>
discards bcafe078ba2cf05417851462cd4506e758839b29 (commit) - Log ----------------------------------------------------------------- commit 9404d5cea31a76376f4d45b697749cbf9b7f7448 Author: Aristotle Pagaltzis <[email protected]> Date: Sat Oct 29 07:50:07 2016 +0200 base: only hide $INC[-1] . from optional loads ----------------------------------------------------------------------- Summary of changes: dist/base/lib/base.pm | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/dist/base/lib/base.pm b/dist/base/lib/base.pm index 163b41b..023f64c 100644 --- a/dist/base/lib/base.pm +++ b/dist/base/lib/base.pm @@ -106,18 +106,22 @@ sub import { my $guard; if ($INC[-1] eq '.' && %{"$base\::"}) { # So: the package already exists => this an optional load - # And: there is a . at the end of @INC => we want to hide it + # And: there is a dot at the end of @INC => we want to hide it # However: we only want to hide it during our *own* `require` # (i.e. without affecting recursive `require`s). # To achieve this overal effect, we use two hooks: - # - The rear hook is placed just before the . and serves - # to hide it just before @INC traversal would reach it, - # which it does by removing itself from @INC and thereby - # moving the . up by one index, causing it to be skipped. - # - The front hook is placed at the front of @INC and serves - # to remove the rear hook if itâs ever reached twice. - # During the initial @INC traversal (by our own `require`) - # it does nothing. + # - A rear hook, which intercepts @INC traversal before the dot is + # reached by sitting immediately in front of the dot. It hides + # the dot by removing itself from @INC, which moves the dot up + # by one index, which causes it to be skipped. + # - A front hook, which sits at the front of @INC and does nothing + # until itâs reached twice, which must be a recursive require. + # If that happens, it removes the rear hook from @INC to keep + # the dot visible. + # Note that this setup works recursively. If a module loaded via + # base.pm itself uses bases.pm, there will be one layer of hooks + # in @INC per base::import call frame on the stack, and they will + # not interfere with each other. my ($reentrant, $front_hook, $rear_hook); unshift @INC, $front_hook = sub { base::__inc::unhook $rear_hook if $reentrant++; () }; splice @INC, -1, 0, $rear_hook = sub { ++$dot_hidden, &base::__inc::unhook; () }; -- Perl5 Master Repository
