How can I connect to Perl usage / requirement so that I can make an exception?

If the file is already loaded, do you still need to connect to use/require so that I can throw an exception? In my upcoming nextgen::blacklist I am trying to die if certain modules are used. I use the object hook method, as stated in perldoc -f require : there is an object with three hooks objects, an array with subref and subref. An example in this post is the hook object, you can find my attempt to hook the sub-ref in nextgen::blacklist .

The syntax I want is something like this:

perl -Mnextgen -E"use NEXT"

 package Foo; use nextgen; use NEXT; 

Ideally, the message is supposed to be like this:

 nextgen::blacklist violation with import attempt for: [ NEXT (NEXT.pm) ] try 'use mro' instead. 

I tried it differently.

 package Class; use Data::Dumper; use strict; use warnings; sub install { unshift @main::INC, bless {}, __PACKAGE__ unless ref $main::INC[0] eq __PACKAGE__ ; } sub reset_cache { undef %main::INC } sub Class::INC { my ( $self, $pmfile ) = @_; warn Dumper [\%main::INC, $pmfile]; #undef %INC; } package main; BEGIN { Class->install; undef %main::INC } use strict; use strict; use strict; use strict; use warnings; use strict; use warnings; 

It seems that %INC is only installed after these hooks. I'm interested in everything that will allow me to throw an exception. If you try to load / reload a module, report its status as a dependency on other modules that do not use my pragma, I want to die.

 package Foo; use NEXT; package main; use Foo; (which uses Next.pm); use NEXT.pm; ## Throw exception 
+4
source share
1 answer

You probably want to put coderef at the top of @INC, as described in perldoc -f require . From there, you can create exceptions to prevent the loading of certain modules, or do nothing to demand that you continue your normal work of finding the module in other @INC entries.

 $ perl -E'BEGIN { unshift @INC, sub { die q{no NEXT} if pop eq q{NEXT.pm}; () }; }; use Carp; say q{success}' success $ perl -E'BEGIN { unshift @INC, sub { die q{no NEXT} if pop eq q{NEXT.pm}; () }; }; use NEXT; say q{success}' no NEXT at -e line 1. BEGIN failed--compilation aborted at -e line 1. 

If you want this behavior to be lexical, you should use Perl %^H hash lists. Dealing with this is a bit difficult, so I would recommend using Devel::Pragma , which can take care of all the gory details for you.

As you pointed out, @INC hooks @INC not be executed for an already loaded module. If you also need to connect to use or require loaded module, then overriding CORE::GLOBAL::require will work, because it is called for every attempt to load the module.

 $ perl -E'BEGIN { *CORE::GLOBAL::require = sub { warn @_ } } use NEXT; use NEXT;' NEXT.pm at -e line 1 NEXT.pm at -e line 1. 

Also, as a supporter of NEXT, I fully approve of preventing people from using it at all. :-)

+5
source

All Articles