Blog::kfly8

prove t/foo/bar/baz.t

Perl5で関数のメタ情報を扱うSub::Metaをリリースしました

Sub::Meta - handle subroutine meta information - metacpan.org

Sub::Metaは、関数の名前、関数の入出力といったメタ情報を扱うためのモジュールです。 Sub::Identify,Sub::Util,Sub::Infoといった類似モジュールはありますが、関数の入出力のメタ情報を扱えないためSub::Metaを書きました。

基本的な使い方は次の通りです。

コードリファレンスを元にメタ情報を抽出できます。

use Sub::Meta;

sub hello($) :mehtod { }
my $meta = Sub::Meta->new(sub => \&hello);
$meta->sub;         # \&hello
$meta->subname;     # hello
$meta->fullname;    # main::hello
$meta->stashname;   # main
$meta->file;        # path/to/file.pl
$meta->line;        # 5
$meta->is_constant; # !!0
$meta->prototype;   # $
$meta->attribute;   # ['method']

コードリファレンス渡すことなく、メタ情報を扱うこともできます。

my $meta = Sub::Meta->new(subname => 'foo');
$meta->subname; # foo

関数の入出力のメタ情報を付加できます。

# 入力
my $parameters = Sub::Meta::Parameters->new(
  args => [
    { name => '$a', type => 'Int' },
    { name => '$b', type => 'Int' },
  ],
  nshift => 1,
);

$meta->set_parameters($paramters);
$meta->parameters->args;
# [
# Sub::Meta::Param->new({ name => '$a', type => 'Int' }),
# Sub::Meta::Param->new({ name => '$b', type => 'Int' })
# ]

# 出力
my $returns = Sub::Meta::Returns->new(
  scalar => 'Int',
  list   => 'Int',
);
$meta->set_returns($returns);
$meta->returns->scalar; # 'Int'

関数の入出力のメタ情報を扱う動機をもう少し掘り下げて、説明します。

Perl5には、関数の入力のバリデーションをするモジュールがParams::Validate,Data::Validator, Smart::Args,Function::Parameters,Type::Paramsなど数多くあります。 モジュールごとに使い勝手が異なり、それは多少ストレスだと思いました。 また、せっかく型アノテートしているので、静的解析したいと思いました。 そのために、関数の入力のメタ情報を取り扱うオブジェクトがあれば、統一されたI/Fで取り扱いしやすくなるのではないかと考えました。

関数の出力についても同様です。

また、拙作のFunction::InterfaceといったPerl5でJavaのようなInterfaceを表現しようとした時に、関数の入出力が取り回ししやすいと便利です。現状のF::IFunction::Parameters,Function::Returnの実装にべたつき、多くの利用用途に対応できず柔軟性に欠けると考えました。

そういったわけで、関数の入出力含めたメタ情報を取り扱えるSub::Metaを作ってみました! よかったら試してもらえると嬉しいです! 以上です!