Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re^4: require() @INC hooks problem

by kcott (Archbishop)
on Dec 28, 2020 at 16:13 UTC ( [id://11125875]=note: print w/replies, xml ) Need Help??


in reply to Re^3: require() @INC hooks problem
in thread require() @INC hooks problem

I got a few ideas from the code to which you linked. Thanks for that. Here's a modified MooselessRequireHookTest.pm:

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").

— Ken

Replies are listed 'Best First'.
Re^5: require() @INC hooks problem
by LanX (Saint) on Dec 28, 2020 at 16:24 UTC
    > "Why is it calling the subroutine with all the previous CODEREF values then the newly created CODEREF?"

    I don't know what that means.

    > 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?

    something like (totally untested)

    sub create_class { my ($class) = @_; my $source = <<~EOF; package $class; use parent 'MooselessRequireHookTest'; 1; EOF eval $source; my $name = $class =~ s(::)(\/)gr; $INC{"$name.pm"} = 'imported via eval'; }

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      here tested code
      use strict; use warnings; use Data::Dump qw/pp dd/; sub create_class { my ($class) = @_; my $source = <<"__CODE__"; package $class; sub import { warn "$class imported"; } __CODE__ eval $source; my $name = $class =~ s(::)(\/)gr; $INC{"$name.pm"} = 'imported via eval'; } BEGIN { create_class('Jabba::Dabba'); } pp \%INC; use Jabba::Dabba;

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        fixed module template, less Perl version dependencies, more flexible and untangled templating

        use strict; use warnings; use Data::Dumper; sub test_tmpl { my ($name) = @_; return $name, <<"__CODE__"; package $name; sub import { warn "$name imported"; } 1; __CODE__ } sub create_module { my ( $module, $source ) = @_; eval $source; (my $name = $module) =~ s(::)(\/)g; my @caller = caller(); $INC{"$name.pm"} = "imported via eval at @caller"; } BEGIN { create_module( test_tmpl('Jabba::Dabba') ); } use Jabba::Dabba; warn Dumper \%INC;

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

      I wrote my last reply at 3.13am (my time). I did see your response about 10 minutes later but my eyes were getting pretty blurry by then: I decided some sleep was in order before looking into that further. :-)

      Twelve hours later, and much refreshed, I see you've posted a lot more code. Thanks for that — I'll look into it and see how that fits with my existing code.

      — Ken

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11125875]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (2)
As of 2024-04-25 22:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found