2

mAを使用しているクラス ()を拡張しようとしていSub::Exporterます。Sub::Exporterサブクラス( )で使いたいmBです。inmAへの呼び出しを通じて に固有のオプションを渡す方法がわかりません。ここにいくつかのテストコードがあります:Sub::ExportermB

#!/usr/bin/env perl

use 5.10.1;
use strict;
use warnings;


{
    package mA;

    use Sub::Exporter -setup => {
            exports => { gmorn => \&build_gmorn },
        };

    sub build_gmorn {
        my ( $class, $name, $arg ) = @_;
        return sub { say "$arg->{salutation}"; }
    }

    sub new { return bless {}, shift }
}

{
    package mB;

    use parent -norequire, 'mA';

    use Sub::Exporter -setup => {
        exports => { gnite => \&build_gnite },
    };

    sub build_gnite {
        my ( $class, $name, $arg ) = @_;
        return sub { say "$arg->{salutation}"; }
    }
}

{
    package mFr;

    use parent -norequire, 'mB';

    mB->import(
       gmorn => { salutation => 'Bon Jour' },
       gnite => { salutation => 'Bon Nuit' }
    );

}

my $obj = mFr->new;

$obj->gmorn();
$obj->gnite();

結果は次のとおりです。

% perl t
"gmorn" is not exported by the mB module at t line 66.

Sub::Exporter仕様を継承する方法はありますか?

4

1 に答える 1

0

あなたはオブジェクト指向の perl を書いているので、あるパッケージから別のパッケージにシンボルをインポートするのは非常に悪い考えです。Perl の標準メカニズムの継承は正常に機能し、ここで行っているように見えるのは、インポートされたメソッドの名前を変更することだけです。

問題はuse parent、他のパッケージのimportルーチンを呼び出さないため、asbuild_gmornにインポートされないことです。mBgmorn

さらに、エラー メッセージが示すように、gmornはモジュールによってエクスポートされmBないため、 にインポートできませんmFr

このように変更mBすると、コードはほとんど機能します。正しいものは失敗するので、mA.pm私は書かなければならなかったのではないことに注意してください。mA->import('gmorn')use mA 'gmorn'

package mB;

mA->import('gmorn');
use parent -norequire, 'mA';

use Sub::Exporter -setup => {
    exports => {
        gmorn => undef,
        gnite => \&build_gnite 
    }
};

sub build_gnite {
    my ( $class, $name, $arg ) = @_;
    return sub { say "$arg->{salutation}"; }
}



アップデート

サブルーチンはジェネレーター関数を呼び出す必要があるため、パラメーターを取得して のuse Sub::Exporter複数のレベルを「通過させる」方法はありません。したがって、あなたの例では呼び出す必要がありますが、そのサブルーチンの知識がないため、実行できません。useimportmB::importmA::build_gmorn

唯一の便利な解決策は、ジェネレーターと生成されたサブルーチンの両方をエクスポートして、呼び出し元のコードが関数を使用するか、生成された関数自体をエクスポートできるようにすることです。

この一連のプログラムは問題なく動作します。

mA.pm

use 5.010;
use warnings;

package mA;

use Sub::Exporter -setup => {
    exports => [
        'build_gmorn',
        gmorn => \&build_gmorn,
    ]
};

sub build_gmorn {
    my ( $class, $name, $arg ) = @_;
    return sub { say "$arg->{salutation}"; }
}

1;

mB.pm

use 5.010;
use warnings;

package mB;

use mA qw/ gmorn build_gmorn /;
use parent 'mA';

use Sub::Exporter -setup => {
    exports => [
        'build_gmorn', 
        gmorn => \&build_gmorn,
        'build_gnite', 
        gnite => \&build_gnite
    ]
};

sub build_gnite {
    my ( $class, $name, $arg ) = @_;
    return sub { say "$arg->{salutation}"; }
}

1;

mFr.pl

use 5.010;
use warnings;

package mFr;

use parent 'mB';

mB->import(
   gmorn => { salutation => 'Bon Jour' },
   gnite => { salutation => 'Bon Nuit' }
);

sub new { return bless {}, shift }

my $obj = mFr->new;

$obj->gmorn();
$obj->gnite();

出力

Bon Jour
Bon Nuit
于 2013-02-06T16:32:05.427 に答える