In perl.git, the branch ap/baseincguard has been updated <http://perl5.git.perl.org/perl.git/commitdiff/aff6087c923733061b9f27eb426d6da4d67f2adf?hp=81e795769268377db011a37079d23891983e71ba>
discards 81e795769268377db011a37079d23891983e71ba (commit) - Log ----------------------------------------------------------------- commit aff6087c923733061b9f27eb426d6da4d67f2adf Author: Aristotle Pagaltzis <[email protected]> Date: Sat Oct 29 09:14:07 2016 +0200 base: only hide $INC[-1] . from optional loads ----------------------------------------------------------------------- Summary of changes: dist/base/lib/base.pm | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/dist/base/lib/base.pm b/dist/base/lib/base.pm index 9a5bcaedb5..5b6b89ba37 100644 --- a/dist/base/lib/base.pm +++ b/dist/base/lib/base.pm @@ -113,25 +113,26 @@ sub import { # So we add a hook to @INC whose job is to hide the dot, but which # first checks checks the callstack depth, because within nested # require()s the callstack is deeper. - # Since CORE::GLOBAL::require makes it unknowable what the exact - # relevant callstack depth will be, we can only record it inside - # a hook, so we put another hook at the front of @INC where it's - # guaranteed to run. - # The way the hook hides the dot is by sitting directly in front - # of the dot and removing itself from @INC. This causes the dot to - # move up by one index in @INC, causing the for(;;) loop inside + # Since CORE::GLOBAL::require makes it unknowable in advance what + # the exact relevant callstack depth will be, we have to record it + # inside a hook. So we put another hook just for that at the front + # of @INC, where it's guaranteed to run -- immediately. + # The dot-hiding hook does its job by sitting directly in front of + # the dot and removing itself from @INC when reached. This causes + # the dot to move up one index in @INC, causing the loop inside # pp_require() to skip it. - # Depending on the specific positions of the hooks in @INC is fine - # even though loaded code can destroy that, because both hooks are - # only active for the top-level require(), during which @INC is in - # our control. - # Note that this setup works fine recursively: if a module loaded - # via base.pm itself uses base.pm, there will be one pair of hooks - # in @INC per base::import call frame, but they do not interfere - # with each other. + # Loaded coded may disturb this precise arrangement, but that's OK + # because the hook is inert by that time. It is only active during + # the top-level require(), when @INC is in our control. The only + # possible gotcha is if other hooks already in @INC modify @INC in + # some way. + # Note that this jiggery hookery works just fine recursively: if + # a module loaded via base.pm uses base.pm itself, there will be + # one pair of hooks in @INC per base::import call frame, but they + # do not interfere with each other. my $lvl; - unshift @INC, sub { unless (defined $lvl) { 1 while defined caller ++$lvl }; () }; - splice @INC, -1, 0, sub { ++$dot_hidden, &base::__inc::unhook unless defined caller $lvl; () }; + unshift @INC, sub { return if defined $lvl; 1 while defined caller ++$lvl; () }; + splice @INC, -1, 0, sub { return if defined caller $lvl; ++$dot_hidden, &base::__inc::unhook; () }; $guard = bless [ @INC[0,-2] ], 'base::__inc::scope_guard'; } require $fn -- Perl5 Master Repository
