m_shige1979のときどきITブログ

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

PerlのExport確認

以前


Perlのモジュールでモジュール名とかを省略する - m_shige1979のささやかな抵抗と欲望の日々

exportで勉強したんだけどちょっと忘れそうなので再度学習

とりあえずサンプル

lib/Sample1.pm
package Sample1;

sub test1{
    return "aaa";
}

sub test2{
    return "bbb";
}

sub test3{
    return "ccc";
}

# 忘れがち
1;

※超基本

sample1.pl
#!/usr/bin/env perl

use strict;
use warnings;

use Sample1;

print Sample1::test1() . "\n";
print Sample1::test2() . "\n";
print Sample1::test3() . "\n";

$ perl -Ilib sample1.pl 
aaa
bbb
ccc
$

まあ、普通に出ます。

sample2.pl
#!/usr/bin/env perl

use strict;
use warnings;

use Sample1;

print test1() . "\n";
print test2() . "\n";
print test3() . "\n";

$ perl -Ilib sample2.pl 
Undefined subroutine &main::test1 called at sample2.pl line 8.
$

でません

Exporterを指定

Sample1.pm
package Sample1;

use base qw(Exporter);
our @EXPORT = qw/test1/;
our @EXPORT_OK = qw/test1/;

sub test1{
    return "aaa";
}

sub test2{
    return "bbb";
}

sub test3{
    return "ccc";
}

# 忘れがち
1;

@EXPORT、@EXPORT_OKにサブルーチンを指定


sample2.pl
#!/usr/bin/env perl

use strict;
use warnings;

use Sample1;

print test1() . "\n";
print test2() . "\n";
print test3() . "\n";

$ perl -Ilib sample2.pl 
aaa
Undefined subroutine &main::test2 called at sample2.pl line 9.
$

test1は指定しているので実行できる

EXPORT_TAGSでグループ分け

lib/Sample1.pm
package Sample1;

use base qw(Exporter);
our @EXPORT = qw/test1/;
our @EXPORT_OK = qw/test1 test2/;
our %EXPORT_TAGS = (
    all  => [ @EXPORT, @EXPORT_OK ],
    test3 => [ qw(test3) ]
);

sub test1{
    return "aaa";
}

sub test2{
    return "bbb";
}

sub test3{
    return "ccc";
}

# 忘れがち
1;

EXPORT_TAGSは%定義なので間違わないようにする

sample3.pl
#!/usr/bin/env perl

use strict;
use warnings;

use Sample1 qw(:all);

print test1() . "\n";
print test2() . "\n";
print test3() . "\n";

$ perl -Ilib sample3.pl 
aaa
bbb
Undefined subroutine &main::test3 called at sample3.pl line 10.
$ 

test1とtest2のサブルーチンを取り込める

sample3_2.pl
#!/usr/bin/env perl

use strict;
use warnings;

use Sample1 qw(:test3);

print test3() . "\n";
print test1() . "\n";
print test2() . "\n";

$ perl -Ilib sample3_2.pl 
"test3" is not exported by the Sample1 module
Can't continue after import errors at sample3_2.pl line 6.
BEGIN failed--compilation aborted at sample3_2.pl line 6.
$

test3は@EXPORT_OKに設定していないのでだめ?

使用するサブルーチンを制限したい場合

実際にモジュール名::サブルーチン名で定義できるので厳密には難しいと思いますけど使用するものを一部に制限することは可能らしい

lib/Sample1.pm
package Sample1;

use base qw(Exporter);
our @EXPORT = qw/test1/;
our @EXPORT_OK = qw/test1 test2/;
our %EXPORT_TAGS = (
    all  => [ @EXPORT, @EXPORT_OK ],
    test2 => [ qw(test2) ],
    test3 => [ qw(test3) ]
);

sub test1{
    return "aaa";
}

sub test2{
    return "bbb";
}

sub test3{
    return "ccc";
}

# 忘れがち
1;

※test2を用意、test2は@EXPORT_OKにある

sample3_3.pl
#!/usr/bin/env perl

use strict;
use warnings;

use Sample1 qw(:test2);

print test2() . "\n";
print test1() . "\n";

$ perl -Ilib sample3_3.pl 
bbb
Undefined subroutine &main::test1 called at sample3_3.pl line 9.
$ 

※test1は呼び出し失敗しているよう

所感

ちょっとむずかしいような気がする。なんかプライベートメソッドみたいなことを期待していたけど、モジュール名を指定することで参照できるのであまりそのへんは難しいかも。
なんかモジュールを作るときに役たつかもしれない。