昨日は、型グロブ構文により、
自らのパッケージの内容を修正したが、
通常、そのようなことを行なう必要はあまりない。
それらは、通常通り直接定義したほうが見やすいからだ。

では、どのようなときに使うかというと、
自分ではなく、別のパッケージ内部を編集する場合だ。

例えば、Employee で行なっていたプロパティ作成は、
Employee クラス自身で実装しなくとも、
動的にサブルーチンが作れる機能を利用して、
別のモジュールから作成してもいいわけだ。

では、プロパティ作成機能を、独立したモジュールとして、
汎用化することを考えてみよう。
こうすれば、色々なモジュールで利用することができる。

モジュール名は、property とする。
Employee では、use property を行なうだけでよく、
property の内部で Employee にプロパティを登録する。

名前を小文字にしたのは、プラグマ的モジュールだからだ。
strict や warnings、integer もプラグマ的モジュールだ。

プラグマ的モジュールは、モジュールを取り込んだ、
つまり use したパッケージに作用をもたらす。
クラスとしてインスタンスを作成して利用したり、
モジュールの関数を呼び出して利用するわけではない。

プラグマ的モジュールを実装するためには、
use されたときに暗黙に呼び出される import ルーチンで、
元のパッケージに対して処理を行なえばいい。

では、property モジュールの枠組みを考えてみよう。

========== property.pm ==========

package property;

use v5.6.0;
use strict;
use warnings;

BEGIN {
    our $Version = '0.00';
}

sub import {
    my $package = shift;
    my %param = @_;
    my $target = caller;

    print "'import' called from $target\n";

    # プロパティ登録の実装
}

1;

========== end of property.pm ==========

import の最初の引数は、パッケージ名だ。
この場合は property となる。これを使うことはあまりない。
残りの引数は、use した時の引数となり、自由に定義できる。

プラグマ的モジュールは、
use したモジュールを知る必要があるが、
そのためには、caller 関数を利用する。
caller をスカラコンテキストで呼び出すと、
呼び出し元のパッケージ名が文字列で返るのだ。

上記には実装コードが含まれていないが、
これだけで use property; とすることができ、
呼び出し元のパッケージ名を得る部分は機能する。

試してみよう。

$ perl -Mproperty -I. -e '';
'import' called from main

呼び出し元のパッケージ名が取得できている。