コンパイル時に外部ファイルから Perl コードをインポートするにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/2282362

  •  21-09-2019
  •  | 
  •  

質問

パーラーズを助けて!「ここにコードを挿入」という単純なアプローチで、コンパイル時に外部ファイルからコードをパッケージに取り込むことができることを知っている人はいますか?

背景:

標準的な PBP スタイルのインサイドアウト クラスがあり、かなり大規模になりつつあります。コードを複数のファイルに分割したいが、クラスは拡張したくない。理想的には、コンパイル時にサンプル モジュール (以下を参照) の「Magic JuJu」セクションにコードを 1 回挿入するだけです。

これを実現する手段として AutoLoader を検討しました。ただし、立ち止まってしまうことが 2 つあります。これらを回避できれば、最適に近い解決策になる可能性があります。

  1. 小さなサブファイルをすべて個別のファイルに分割したくありません。適切なサイズのファイルをさらにいくつか追加するだけです (ただし、呼び出し側でサブ スタブを使用することは問題ありません)。そして

  2. すべてのサブでコンパイルを延期したくありません。最初の使用時にコンパイルしておきたいサブタイトルがいくつかあります。ただし、これはおそらく取引の妨げにはなりません。

Moose が「ロール」を提供していることは知っており、これはこれでうまく機能すると信じていますが、さまざまな理由から、Moose はこのプロジェクトのオプションではなく、Mouse もオプションではありません。

「Magic JuJu」の場所で「require q(some/file)」を使用しましたが、これでは永続変数のスコープが維持されません。外部ファイルからの subs はオブジェクト属性ハッシュを正しく「認識」しません (つまり、ファイルの先頭に require を置くと同じ効果が得られます)。常にセッターとゲッターを使用することでこれを回避できます。したがって、これは取引を妨げるものではありませんが、多少のコーディング時間と実行のオーバーヘッドが必要になるため、それは避けたいと考えています。

最後に、私はクラスを拡張したくありません。すでに多重継承を持っています。私は、単純な「ここにコードを挿入」というアプローチで、コンパイル時にコードを一度に取り込みたいだけです。

要約すれば:

  1. (必須) コードを外部ファイルからパッケージ名前空間にインポートします
  2. (必須) コンパイル時のみ、または最小限の実行時のオーバーヘッドでのみ実行されます。
  3. (必須) クラスを拡張しません
  4. (望ましい) 名誉は場所のスコープを挿入します

以下の「Magic JuJu」コメントを含むコード例:

package T;

use strict;
use warnings;

########## BEGIN object persistent variables scope block ############
{
  my %Attr_Name_Env;

  ## Constructor 'new'
  #
  sub new {
    ## Get and confirm arguments
    #
    my $class      = shift;
    my $href_arg = {@_};
    my $name_env = $href_arg->{'name_env'};

    ## Bless anon scalar into class
    #
    my $obj_new   = bless anon_scalar(), $class;
    my $idx_self  = ident $obj_new;

    # Populate object attributes
    #
    $Attr_Name_Env{ $idx_self } = $name_env;

    return $obj_new;
  }
  ## END Constructor 'new'

  sub DESTROY {... as you do ...}

  sub t_get_name_env {
    my $self      = shift;
    my $idx_self  = ident $self;
    return $Attr_Name_Env{ $idx_self };
  }

  ## insert magic juju here

}
########## END object persistent variables scope block ############

1;

おそらく、slurp と eval を含む BEGIN ブロックです...

役に立ちましたか?

解決

あなただけのモジュールを使用して所望の潜水艦をインポートすることができます。

use MyMod qw( wanted_sub_1 wanted_sub2 );
あなたは、ターゲットモジュールのimportを変更する必要がありますあなたの属性のハッシュへのアクセスを取得するには、

package MyClass;
use MyMod { attrib1 => \%attrib1, attrib2 => \%attrib2 }, qw( wanted_sub1 wanted_sub2 );

MyModimportは、初期のハッシュ引数を介して閉鎖されているコード、参考文献を作成し、MyClass名前空間にそれらをインストールします。

他のヒント

あなたが結果と一緒に暮らすために喜んでいる場合は、

は、フィルター::マクロ

scroll top