4

ファイルが既にロードされている場合use/require、例外をスローできるようにフックする方法はありますか? 私の今後の予定nextgen::blacklistでは、特定のモジュールが使用されている場合、私は死にたいと思っています。で述べたように、私は object-hook メソッドを使用していますperldoc -f require: 3 つのようなフックobjectsubref を持つ配列、およびsubrefがあります。この投稿の例は object-hook です。sub-ref フックの私の試みは にありnextgen::blacklistます。

私が望んでいる構文は次のようなものです:

perl -Mnextgen -E"use NEXT"

package Foo;
use nextgen;
use NEXT;

理想的には、次のようなメッセージをスローすることになっています。

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

私はこれをさまざまな方法で試しました。

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;

これらのフックの後に%INCのみ設定されているようです。例外をスローできるものに興味があります。私のプラグマを使用しない他のモジュールの依存関係としてのステータスにもかかわらず、モジュールをロード/リロードしようとすると、私は死にたいです。

package Foo;
use NEXT;

package main;
use Foo; (which uses Next.pm);
use NEXT.pm; ## Throw exception
4

1 に答える 1

5

で説明されているように、最初の @INC に coderef を配置することをお勧めしperldoc -f requireます。そこから、例外を発生させて特定のモジュールがロードされないようにするか、require が他の @INC エントリでモジュールを検索するという通常の仕事を続けられるように何もしないでください。

$ 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.

その動作をレキシカルにしたい場合は、Perl のヒント hash を利用する必要があります%^H。それを処理するのは少し手間Devel::Pragmaがかかるので、面倒な詳細をすべて処理できる を使用することをお勧めします。

ご指摘のとおり、@INCすでにロードされているモジュールに対してフックは実行されません。useロードされたモジュールのまたはにもフックする必要がある場合は、モジュールをロードしようとするたびに呼び出されるためrequire、オーバーライドが機能します。CORE::GLOBAL::require

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

また、NEXT のメンテナーとして、人々が NEXT を使用できないようにすることを完全に承認します。:-)

于 2010-10-06T02:15:04.173 に答える