[Perl][翻訳] Exporter.pm の perldoc /日本語訳

# (凡例)

コア中のコアモジュールである Exporter の POD について、ウェブを眺めてみたところ整理された邦訳が存在しないようだったので、訳しました。オブジェクト指向 Perl では使いませんが、CPAN の資産を利用したりコードリーディングのためには、理解は必須だと思いますので。

- Perl 5.36.0 に附属する Exporter 5.77 のドキュメントに準拠 ([原文](https://perldoc.perl.org/5.36.0/Exporter))。
- 翻訳について生じる範囲の著作権は放棄 ([CC0](https://creativecommons.org/publicdomain/zero/1.0/)) します。
- 直訳では意味が取りにくい部分を勝手に訳補した箇所は〔〕で示す。

# 名前

Exporter - モジュールのための、デフォルトの import メソッドの実装

# 概要

モジュール *YourModule.pm* で：

```perl
package YourModule;
use Exporter 'import';
our @EXPORT_OK = qw(munge frobnicate);  # 要求に応じてエクスポートするシンボル
```

または

```perl
package YourModule;
require Exporter;
our @ISA = qw(Exporter);  # Exporter の全メソッドを継承する
our @EXPORT_OK = qw(munge frobnicate);  # 要求に応じてエクスポートするシンボル
```

または

```perl
package YourModule;
use parent 'Exporter';  # Exporter の全メソッドを継承する
our @EXPORT_OK = qw(munge frobnicate);  # 要求に応じてエクスポートするシンボル
```

`YourModule` を use したい他のファイルでは：

```perl
use YourModule qw(frobnicate);      # リストされたシンボルをインポート
frobnicate ($left, $right)          # YourModule::frobnicate を呼ぶ
```

あなたがモダン Perl のコードで使いたいと思うかもしれない、これらのさらなる変種については、以下の ["グッド・プラクティス"](#グッドプラクティス) に目を通すとよい。

# 説明

Exporter モジュールは、あるモジュールがその関数や変数をユーザーの名前空間にエクスポートすることを可能にする、`import` メソッドを実装している。数多くのモジュールが、それ自身の `import` メソッドを実装せずに、Exporter モジュールを使う。なぜなら Exporter は、通常の事例にとって最適化された実装とともに、とてもフレキシブルなインターフェースを提供しているからだ。

モジュールの `use` 宣言を処理するとき、Perl は自動的にそのモジュールの `import` メソッドを呼ぶ。モジュールと `use` については、[perlfunc](https://perldoc.perl.org/perlfunc) と [perlmod](https://perldoc.perl.org/perlmod) がドキュメント化している。Exporter を理解するために、モジュールの概念、および `use` 宣言が働く仕方を理解することは重要である。

## エクスポートのやり方

〔Exporter を利用する〕モジュールの側では、配列 `@EXPORT` および `@EXPORT_OK` は、デフォルトでユーザー名前空間にエクスポートされるシンボルのリストと、エクスポートするようにユーザーから要求できるシンボルのリストとを、それぞれ保持する。シンボルは、関数・スカラー変数・配列・ハッシュ・型グロブを意味できる。関数の前に置かれるアンパサンドがオプショナルであることを除いて、シンボルはフルネームで与えられねばならない。例えば

```perl
our @EXPORT    = qw(afunc $scalar @array);   # afunc は関数
our @EXPORT_OK = qw(&bfunc %hash *typeglob); # &bfunc では明示的なプレフィクス
```

もし関数名だけをエクスポートしているなら、アンパサンドは省略することが奨められる。こうすると、実行がより速いものになる。

## 何をエクスポートするかの選択

メソッド名をエクスポートしては**ならない**！

適当な理由がなければ、他のどんなものもエクスポートしては**ならない**！

エクスポートはモジュールユーザーの名前空間を汚染する。エクスポートしなければならないのなら、`@EXPORT` より `@EXPORT_OK` を好んで使おうとし、名前衝突のリスクを減らすために、短い、またはよく使われるシンボル名を避けよ。

一般的に言って、エクスポートされていないどんなものでも、`YourModule::item_name` (または `$blessed_ref->method`) 構文を使うことで、そのモジュールの外部からアクセス可能である。慣習では、名前の先頭にアンダースコアを足すことで、それらが '内部用' であってパブリックな利用には適さないということを、インフォーマルに伝えることができる。

(実際には、こうすればプライベートな関数をつくることも可能である：

```perl
my $subref = sub { ... };
$subref->(@args);            # 関数として呼び出す
$obj->$subref(@args);        # メソッドとして使う
```

もっともメソッドとしての利用にあっては、それでどうやって継承システムを機能させるのかは、あなた自身で解決しなければならない問題だが)

普遍的なルールとして、もしモジュールがオブジェクト指向であろうとしているのなら、何もエクスポートすべきではない。また、もしそれが関数のコレクションにすぎないのなら、`@EXPORT` は論外、`@EXPORT_OK` を心して用いるがよい。また、エクスポートリストでは、関数とメソッドの名前には、アンパサンド付きの名前よりは裸の単語を使うことが好ましい。

その他のモジュールデザインのガイドラインは、[perlmod](https://perldoc.perl.org/perlmod) で見ることができる。

## インポートのやり方

あなたのモジュールを use したがっているその他のファイルにおいては、あなたのモジュールをロードしてシンボルをインポートするのには、３つの基本的なやり方がある：

- `use YourModule;`

これは、YourModule の `@EXPORT` から `use` 宣言がされた名前空間へ、すべてのシンボルをインポートする。

- `use YourModule ();`

これは、perl にあなたのモジュールをロードさせて、シンボルは何もインポートしない。

- `use YourModule qw(...);`

これは、呼び出し側によってリストされたシンボルだけを、その名前空間へインポートする。すべてのリストされたシンボルは、あなたが用意した `@EXPORT` か `@EXPORT_OK` の中になければならず、さもなければエラーになる。Exporter の進んだエクスポート機能はこれと似たような仕方でアクセスされるが、その際にはシンボル名とは構文的に区別されたリストのエントリが利用される。

より進んだ機能を使おうとしない限り、以上がたぶん、Exporter を使うためにあなたが知る必要のあるすべてのことである。

# 進んだ機能

## 特殊なインポートリスト

インポートリストのエントリのどれかが「!」「:」「/」で始まっていれば、インポートする名前のリストに対する、一連の追加・除外を指定したリストとして扱われる。指定子は左から右へ処理され、次のどれかの形である：

```perl
[!]name         この名前だけ
[!]:DEFAULT     @EXPORT の全部の名前
[!]:tag         $EXPORT_TAGS{tag} 無名配列〔リファレンス〕の全部の名前
[!]/pattern/    @EXPORT と @EXPORT_OK の、マッチする全部の名前
```

〔[!] は、! が先行しうることを示す。〕先行する ! は、マッチした名前を、インポートする名前のリストから除外すべきことを示している。先頭にある指定子が除外なら、その前に :DEFAULT があるものとして扱われる。ただし、もしデフォルトセットとともに加えて余分な名前をインポートしたいというだけのことなら、依然として明示的に :DEFAULT を含めてやる必要がある。

例えば、*Module.pm* がこのように定義しているとする：

```perl
our @EXPORT      = qw(A1 A2 A3 A4 A5);
our @EXPORT_OK   = qw(B1 B2 B3 B4 B5);
our %EXPORT_TAGS = (T1 => [qw(A1 A2 B1 B2)], T2 => [qw(A1 A2 B3 B4)]);
```

@EXPORT や @EXPORT_OK の中では、タグは使えないことに注意せよ。

EXPORT_TAGS に含まれる名前は、また @EXPORT か @EXPORT_OK にも出現していなくてはならない。

この Module を利用するアプリケーションでは、次のように書ける：

```perl
use Module qw(:DEFAULT :T2 !B3 A3);
```

また他の例では：

```perl
use Socket qw(!/^[AP]F_/ !SOMAXCONN !SOL_SOCKET);
use POSIX  qw(:errno_h :termios_h !TCSADRAIN !/^EXIT/);
```

(// を使った) もっともよくあるパターンでは、`/EXIT/` でなく `/^EXIT/` 等と、冒頭を ^ でアンカーする必要がある、ということも銘記しよう。

`BEGIN { $Exporter::Verbose=1 }` と詠唱すれば、どう指定子が処理されているかや、実際に何がモジュールにインポートされているかを見ることができる。

## Exporter の import メソッドを使わずにエクスポートする

Exporter には、Exporter の import メソッドを直接呼ぶことができない状況で使われる特殊なメソッド、'export_to_level' がある。export_to_level メソッドは、このようである：

```perl
MyPackage->export_to_level(
    $where_to_export, $package, @what_to_export
);
```

ここで `$where_to_export` は整数であり、コールスタックをどこまで遡ってシンボルをエクスポートするかを指示する。`@what_to_export` は配列であり、どのシンボルたちをエクスポートしたいかを指示する (通例これは `@_` である)。引数 `$package` は、今のところ活用されていない。〔以下で見るように、import 内で @_ を置くならば、先頭にパッケージ名が渡ってきて辻褄が合う〕

例として、あるモジュール A を持っているとしよう。それにはすでに import 関数がある：

```perl
package A;

our @ISA = qw(Exporter);
our @EXPORT_OK = qw($b);

sub import
{
    $A::b = 1;     # さして役立ちもしない import メソッド
}
```

そして、パッケージ A を呼び出したモジュールにまで、シンボル `$A::b` をエクスポートしたい。Exporter が、継承メカニズムを通じて import メソッドに依存して動いている以上、このままでは Exporter::import() が呼ばれることはない。かわりに、次のように書く：

```perl
package A;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw($b);

sub import
{
    $A::b = 1;
    A->export_to_level(1, @_);
}
```

これは、カレントパッケージの一階層「上に」シンボルをエクスポートする――すなわち： パッケージ A を use したプログラム、ないしはモジュールに。

注意： export_to_level を呼ぶ以前に、いっさい `@_` に変更を加えないように――さもなくば、あなたのパッケージを利用する人々に、まさに説明不能なことが起こるでしょう！

## Exporter を継承せずにエクスポートする

あなたの `@ISA` に Exporter を含めることで、Exporter の import() メソッドは継承されるが、なおまた多分必要としない、継承ツリーをややこしくするような、他のさまざまなヘルパーメソッドも継承される。これを避けるのに、こうできる：

```perl
package YourModule;
use Exporter qw(import);
```

これで、Exporter 自身の import() メソッドが、YourModule にエクスポートされる。すべてが元通りに動く。あなたが Exporter を `@YourModule::ISA` に含める必要がないことを除いては。

注意： この機能は、perl 5.8.3 に伴ってリリースされた、Exporter の version 5.57 で導入された。

## モジュールバージョンのチェック

Exporter モジュールは、あるモジュールから数字をインポートしようとする試みを、`$module_name->VERSION($value)` の呼び出しへと変換する。これは、使っているそのモジュールのバージョンが、要求するバージョンより大きいかまたは等しいことをバリデートするのに利用できる。

歴史的事情から、Exporter はただ `VERSION` に委譲するだけの `require_version` メソッドを提供している。もともと、`UNIVERSAL::VERSION` のまだ存在していなかった頃には、Exporter は `require_version` を呼んでいた。

`UNIVERSAL::VERSION` メソッドが `$VERSION` ナンバーを単純な数値として扱っているので、バージョン 1.10 は 1.9 より小さいとみなされるだろう。この理由から、例えば 1.09 のように、数字の少なくとも小数点以下 2 桁を確保しておくことが、強く推奨される。

## 未知のシンボルのマネージ

特定のシンボルがエクスポートされることを防ぎたい、という状況もありうる。典型的には、それが存在しないシステムもあるような関数や定数を、エクステンションが含んでいる場合がこれにあたる。

エクスポートできないシンボルの名前は `@EXPORT_FAIL` 配列にリストすること。

あるモジュールがこれらのシンボルのどれか一つでもインポートしようとするとき、エラーを発生させる前に Exporter は、状況をハンドルするための機会を〔エクスポートする側の〕モジュールに許す。Exporter は〔エクスポートする側のモジュールが自身で定義、または Exporter から継承する〕export_fail メソッドを、失敗したシンボルのリストで〔内部処理として次のコードのように〕呼び出す：

```perl
@failed_symbols = $module_name->export_fail(@failed_symbols);
```

ここで `export_fail` メソッドが空リストを返すなら、エラーは登録されず、要求されたすべてのシンボルはエクスポートされる。返されるリストが空でないなら、おのおののシンボルについてエラーが発生し、エクスポートは失敗する。Exporter は、リストを変更せずただ返すだけの、デフォルトの `export_fail` メソッドを提供している。

`export_fail` メソッドの使途としては、シンボルに即してより良いエラーメッセージを出すことや、遅延アーキテクチャチェック (デフォルトで `@EXPORT_FAIL` にシンボルを多めに入れておき、誰かが実際に使おうとして、高くつくチェックによってそれらがそのプラットフォームで実際に使用可能だと判明した暁には、そこから取り除く) の実行が挙げられる。

## タグを扱うユーティリティ関数

`%EXPORT_TAGS` 内にリストされたシンボルはまた `@EXPORT` か `@EXPORT_OK` のいずれかに現れていなければならないから、タグ付けられたシンボル集合の、`@EXPORT` ないし `@EXPORT_OK` への追加を簡易ならしめるように、二つのユーティリティ関数が提供されている：

```perl
our %EXPORT_TAGS = (foo => [qw(aa bb cc)], bar => [qw(aa cc dd)]);

Exporter::export_tags('foo');     # aa, bb と cc を @EXPORT に追加
Exporter::export_ok_tags('bar');  # aa, cc と dd を @EXPORT_OK に追加
```

タグではない名前については `@EXPORT` または `@EXPORT_OK` にそのまま追加されるが、ミススペルされたタグ名が通知なく `@EXPORT` や `@EXPORT_OK` に追加されるのを避けるため、(`-w` があれば) 警告をトリガーするだろう。未来のバージョンでは、これは致命的エラーになる可能性がある。

## 合併タグの生成

`%EXPORT_TAGS` の中にさまざまなシンボルカテゴリが存在する場合、"use" 文を単純にするため、利便性をはかる ":all" を作っておくことが通例、有益である。

一番単純な作成法は：

```perl
our  %EXPORT_TAGS = (foo => [qw(aa bb cc)], bar => [qw(aa cc dd)]);

 # 重複を削って、他のすべての ":class" タグを ":all" クラスに足す
 {
   my %seen;

   push @{$EXPORT_TAGS{all}},
     grep {!$seen{$_}++} @{$EXPORT_TAGS{$_}} foreach keys %EXPORT_TAGS;
 }
```

*CGI.pm* は、自身のカテゴリのうちいくつか (本当に全部ではない) を含んだ ":all" タグを作る。一つの小さな変更だけで可能になる：

```perl
# 重複を削って、他のいくつかの ":class" タグを ":all" クラスに足す
{
  my %seen;

  push @{$EXPORT_TAGS{all}},
    grep {!$seen{$_}++} @{$EXPORT_TAGS{$_}}
      foreach qw/html2 html3 netscape form cgi internal/;
}
```

`%EXPORT_TAGS` のタグ名には ':' が先行しないことに注意せよ。

## `AUTOLOAD` される定数

たくさんのモジュールが、めったに使われない値をコンパイルしメモリを浪費するのを避けようと、定数サブルーチンの `AUTOLOAD` を役立てている (定数サブルーチンの詳細については [perlsub](https://perldoc.perl.org/perlsub) を見よ)。このような定数サブルーチンの呼び出しは、それが定数であることをコンパイル時にチェックできないので、最適化によってコンパイル時に除去されない。

コンパイル時にプロトタイプがわかるときでさえ、サブルーチンの実体はわからない (それはまだ `AUTOLOAD` されていなかった)。サブルーチンの呼び出しが定数値で安全に置き替えられることを検出するには、`()` プロトタイプとサブルーチンの実体の、両方ともが、コンパイル時に perl によって確かめられるのでなければならない。

一つの回避策として、定数を `BEGIN` ブロックの中で一度呼び出すという手がある：

```perl
package My ;

use Socket ;

foo( SO_LINGER );  ## SO_LINGER は最適化によって除去され「ない」; 実行時に呼ばれる
BEGIN { SO_LINGER }
foo( SO_LINGER );  ## SO_LINGER は最適化によってコンパイル時に除去される。
```

これは、のちに `My` パッケージにおいて SO_LINGER と出くわす以前に、`SO_LINGER` の `AUTOLOAD` が生じるよう強制する。

もしあなたが `AUTOLOAD` するパッケージを書いているのであれば、他のパッケージによって明示的にインポートされる定数、またはあなたのパッケージが `use` されるときいつも使われるような定数については、`AUTOLOAD` を強制することを検討しよう。

# グッド・プラクティス

## `@EXPORT_OK` とその仲間たちの宣言

`Exporter` を `strict` と `warnings` の標準的プラグマの下で使うとき、パッケージ変数 `@EXPORT_OK`, `@EXPORT`, `@ISA` 等を宣言するには `our` キーワードが必要である。

```perl
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(munge frobnicate);
```

5.6 **未満**の Perl との後方互換性が重視されるときは、かわりに `use vars` ステートメントが書かれなければならない。

```perl
use vars qw(@ISA @EXPORT_OK);
@ISA = qw(Exporter);
@EXPORT_OK = qw(munge frobnicate);
```

## 安全に遊ぼう

`require Exporter` といった実行時ステートメントの使用や、パッケージ変数の代入については、警戒しておくべきことがいくつかある。意識しないプログラマーにとって、それらは非常に神機霊妙なものでありうる。これは例えば、相互再帰的モジュールにおいて起こりうることである。相互再帰的モジュールでは、関連するコンストラクションが実行されるタイミングによって、弊害が出る。

そうしたことを全然考えないで済ます理想的な方法は、`BEGIN` ブロックと単純な import メソッドを使うことである。そうすると、["概要"](#概要) に掲げたコードの最初のものは、次のようにして書き直されるだろう：

```perl
package YourModule;

use strict;
use warnings;

use Exporter 'import';
BEGIN {
  our @EXPORT_OK = qw(munge frobnicate);  # 要求に応じてエクスポートするシンボル
}
```

あるいは、Exporter から継承する必要があるのなら：

```perl
package YourModule;

use strict;
use warnings;

BEGIN {
  require Exporter;
  our @ISA = qw(Exporter);  # Exporter の全メソッドを継承する
  our @EXPORT_OK = qw(munge frobnicate);  # 要求に応じてエクスポートするシンボル
}
```

この `BEGIN` は、*Exporter.pm* のロードと `@ISA` および `@EXPORT_OK` への代入とが、`use` がするように直ちに生じることを保証して、物事がどうもよじれてしまったり、または単に明白におかしかったりする余地を残さない。

`Exporter` のロード、および継承という観点では、`base` や `parent` といったモジュールを利用するという代案もある。

```perl
use base qw(Exporter);
# or
use parent qw(Exporter);
```

これらのステートメントは、`BEGIN { require Exporter; our @ISA = qw(Exporter); }` の置き替えとして好ましく、おなじコンパイル時作用を保っている。基本的な違いは、`base` のコードは `fields` プラグマの宣言と一緒にうまくはたらく一方で、`parent` は、ただ IS-A 関係を確立するだけのより古い `base` のコードを効率化したバージョンである、ということだ。

さらなる違いについては、[base](https://perldoc.perl.org/base) および [parent](https://perldoc.perl.org/parent) のドキュメンテーションとコードを参照せよ。

こうした実行時 vs. コンパイル時の罠に対する、また別の根治法に、[Exporter::Easy](https://metacpan.org/pod/Exporter::Easy) がある。これは、すべてのボイラープレート・コードを use 文の中で一発で可能にしてしまう、Exporter のラッパーである。

```perl
use Exporter::Easy (
    OK => [ qw(munge frobnicate) ],
);
# @ISA は自動的にセットアップされる
# すべての代入はコンパイル時に起こる
```

## エクスポートすべきでないもの

["何をエクスポートするかの選択"](#何をエクスポートするかの選択) で、エクスポートしないよう、これらはすでに警告されている：

- メソッド名 (なぜならそうしたいと思わないだろうし、あなたがしたいと思うことをそれはしないだろうから)
- デフォルトでは何も (なぜならユーザーをびっくりさせたいとは思わないだろうから……悪い意味で)
- 必要のないものは何も (なぜなら less is more だから)

一つこのリストに加えるとすれば、変数名をエクスポートしては**ならない**。なるほど `Exporter` はそうすることを許可しているが、だからといって、そのことがそうすべきであるということを直ちに含意するわけではない。

```perl
@EXPORT_OK = qw($svar @avar %hvar); # するな！
```

変数のエクスポートは、良い考えではない。それらは見えないところで変更されうるし、追跡し修正することが困難をきわめるほどの遠くから、恐ろしい影響を招き入れる。信じてくれ： そうする価値はない。

クラス全体に通じる設定を set/get する能力を提供したいのなら、サブルーチンまたはクラスメソッドとして、かわりにアクセサを提供するのが最善である。

# 関連項目

`Exporter` は、シンボルをエクスポートする能力を持った唯一のモジュールでは断じてない。CPAN には、そういうものが山ほど見つかる。それらのいくつかは、より軽量である。いくつかは、改善された API と機能とを提供している。あなたの必要に適合するものを選ぶとよい。以下は、そうしたモジュールたちのサンプルリストである。

```
Exporter::Easy
Exporter::Lite
Exporter::Renaming
Exporter::Tidy
Sub::Exporter / Sub::Installer
Perl6::Export / Perl6::Export::Attrs
```

# ライセンス

This library is free software. You can redistribute it and/or modify it under the same terms as Perl itself.