package MooselessRequireHookTest;
use 5.032;
use warnings;
sub new {
my ($class) = @_;
return bless {} => $class;
}
sub dynamic_require {
my ($self, $ns_extension) = @_;
state $hook_source = {};
state $inc_updated = 0;
my $class = join '::', __PACKAGE__, $ns_extension;
my $filename_key = $class =~ s{::}{/}gr . '.pm';
unless (exists $hook_source->{$filename_key}) {
my $source = <<~EOF;
package $class;
use parent 'MooselessRequireHookTest';
1;
EOF
$hook_source->{$filename_key} = \$source;
}
state sub inc_hook {
my ($coderef, $filename) = @_;
warn "\$coderef[$coderef] \$filename[$filename]\n";
return $hook_source->{$filename};
};
unless ($inc_updated) {
push @INC, \&inc_hook;
$inc_updated = 1;
}
eval "require $class;";
return;
}
1;
I added this to the end of sscce_mooseless_require_hook_test.t:
warn '-' x 10, ' @INC ', '-' x 10, "\n";
warn "$_\n" for @INC;
warn '-' x 26, "\n";
Here's a new, sample prove run:
$ prove -v sscce_mooseless_require_hook_test.t
sscce_mooseless_require_hook_test.t ..
1..8
ok 1 - Test MooselessRequireHookTest::->new()
ok 2 - 'Test MooselessRequireHookTest::->new() ISA' isa 'MooselessRequ
+ireHookTest'
ok 3 - Test MooselessRequireHookTest::Test1->new()
ok 4 - 'Test MooselessRequireHookTest::Test1->new() ISA' isa 'Mooseles
+sRequireHookTest::Test1'
ok 5 - Test MooselessRequireHookTest::Test2->new()
ok 6 - 'Test MooselessRequireHookTest::Test2->new() ISA' isa 'Mooseles
+sRequireHookTest::Test2'
ok 7 - Test MooselessRequireHookTest::A::B::C->new()
ok 8 - 'Test MooselessRequireHookTest::A::B::C->new() ISA' isa 'Moosel
+essRequireHookTest::A::B::C'
$coderef[CODE(0x600867f00)] $filename[MooselessRequireHookTest/Test1.p
+m]
$coderef[CODE(0x600867f00)] $filename[MooselessRequireHookTest/Test2.p
+m]
$coderef[CODE(0x600867f00)] $filename[MooselessRequireHookTest/A/B/C.p
+m]
---------- @INC ----------
/home/ken/tmp/pm_sscce_require_hook/lib
/home/ken/perl5/perlbrew/perls/perl-5.32.0/lib/site_perl/5.32.0/cygwin
+-thread-multi
/home/ken/perl5/perlbrew/perls/perl-5.32.0/lib/site_perl/5.32.0
/home/ken/perl5/perlbrew/perls/perl-5.32.0/lib/5.32.0/cygwin-thread-mu
+lti
/home/ken/perl5/perlbrew/perls/perl-5.32.0/lib/5.32.0
CODE(0x600867f00)
--------------------------
ok
All tests successful.
Files=1, Tests=8, 0 wallclock secs ( 0.02 usr 0.01 sys + 0.08 cusr
+ 0.05 csys = 0.15 CPU)
Result: PASS
So, the CODEREF is only run once for each invocation and @INC only has one hook.
Compare that output with what I previously showed in "Re^6: require() @INC hooks problem [non-Moose]".
I put the changes (not the warn statements) into the original module:
all (98) tests passed without any problems.
With regard to your suggestion of "Just eval the code and update %INC",
I'm not following you in terms of how that might be implemented.
Could you provide a code example?
I notice you're referencing the OP code.
Please see the sub-thread starting at "Re^4: require() @INC hooks problem [non-Moose]".
Moose was never an issue here but, given your request, and
stated aversion to Moose, that provides a non-Moose version of the SSCCE code.
I was hoping for an answer to
"Why is it calling the subroutine with all the previous CODEREF values then the newly created CODEREF?"
(see "Re^2: require() @INC hooks problem").
|