[](
https://github.com/kfly8/p5-Sub-Meta/actions) [](
https://coveralls.io/r/kfly8/p5-Sub-Meta?branch=master) [](
https://metacpan.org/release/Sub-Meta)
# NAME
Sub::Meta - handle subroutine meta information
# SYNOPSIS
```perl
use Sub::Meta;
sub hello($) :mehtod { }
my $meta = Sub::Meta->new(sub => \&hello);
$meta->subname; # => 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']
$meta->is_method # undef
$meta->parameters # undef
$meta->returns # undef
# setter
$meta->set_subname('world');
$meta->subname; # world
$meta->fullname; # main::world
# apply to sub
$meta->apply_prototype('$@');
$meta->prototype; # $@
Sub::Util::prototype($meta->sub); # $@
```
And you can hold meta information of parameter type and return type. See also [Sub::Meta::Parameters](
https://metacpan.org/pod/Sub%3A%3AMeta%3A%3AParameters) and [Sub::Meta::Returns](
https://metacpan.org/pod/Sub%3A%3AMeta%3A%3AReturns).
```perl
$meta->set_parameters(args => ['Str']));
$meta->parameters->args; # [ Sub::Meta::Param->new({ type => 'Str' }) ]
$meta->set_args(['Str']);
$meta->args; # [ Sub::Meta::Param->new({ type => 'Str' }) ]
$meta->set_returns('Str');
$meta->returns->scalar; # 'Str'
$meta->returns->list; # 'Str'
```
And you can compare meta informations:
```perl
my $other = Sub::Meta->new(subname => 'hello');
$meta->is_same_interface($other); # 1
$meta eq $other; # 1
```
# DESCRIPTION
`Sub::Meta` provides methods to handle subroutine meta information. In addition to information that can be obtained from subroutines using module [B](
https://metacpan.org/pod/B) etc., subroutines can have meta information such as arguments and return values.
# METHODS
## new
Constructor of `Sub::Meta`.
```perl
use Sub::Meta;
use Types::Standard -types;
# sub Greeting::hello(Str) -> Str
Sub::Meta->new(
fullname => 'Greeting::hello',
is_constant => 0,
prototype => '$',
attribute => ['method'],
is_method => 1,
parameters => { args => [{ type => Str }]},
returns => Str,
);
```
Others are as follows:
```perl
# sub add(Int, Int) -> Int
Sub::Meta->new(
subname => 'add',
args => [Int, Int],
returns => Int,
);
# method hello(Str) -> Str
Sub::Meta->new(
subname => 'hello',
args => [{ message => Str }],
is_method => 1,
returns => Str,
);
# sub twice(@numbers) -> ArrayRef[Int]
Sub::Meta->new(
subname => 'twice',
args => [],
slurpy => { name => '@numbers' },
returns => ArrayRef[Int],
);
# Named parameters:
# sub foo(Str :a) -> Str
Sub::Meta->new(
subname => 'foo',
args => { a => Str },
returns => Str,
);
# is equivalent to
Sub::Meta->new(
subname => 'foo',
args => [{ name => 'a', isa => Str, named => 1 }],
returns => Str,
);
```
## ACCESSORS
### sub
A subroutine reference.
### set\_sub
Setter for subroutine reference.
```perl
sub hello { ... }
$meta->set_sub(\&hello);
$meta->sub # => \&hello
```
### subname
A subroutine name, e.g. `hello`
### set\_subname($subname)
Setter for subroutine name.
```perl
$meta->subname; # hello
$meta->set_subname('world');
$meta->subname; # world
Sub::Util::subname($meta->sub); # hello (NOT apply to sub)
```
### apply\_subname($subname)
Sets subroutine name and apply to the subroutine reference.
```perl
$meta->subname; # hello
$meta->apply_subname('world');
$meta->subname; # world
Sub::Util::subname($meta->sub); # world
```
### fullname
A subroutine full name, e.g. `main::hello`
### set\_fullname($fullname)
Setter for subroutine full name.
### stashname
A subroutine stash name, e.g. `main`
### set\_stashname($stashname)
Setter for subroutine stash name.
### subinfo
A subroutine information, e.g. `['main', 'hello']`
### set\_subinfo(\[$stashname, $subname\])
Setter for subroutine information.
### file
A filename where subroutine is defined, e.g. `path/to/main.pl`.
### set\_file($filepath)
Setter for `file`.
### line
A line where the definition of subroutine started, e.g. `5`
### set\_line($line)
Setter for `line`.
### is\_constant
A boolean value indicating whether the subroutine is a constant or not.
### set\_is\_constant($bool)
Setter for `is_constant`.
### prototype
A prototype of subroutine reference, e.g. `$@`
### set\_prototype($prototype)
Setter for `prototype`.
### apply\_prototype($prototype)
Sets subroutine prototype and apply to the subroutine reference.
### attribute
A attribute of subroutine reference, e.g. `undef`, `['method']`
### set\_attribute($attribute)
Setter for `attribute`.
### apply\_attribute(@attribute)
Sets subroutine attributes and apply to the subroutine reference.
### is\_method
A boolean value indicating whether the subroutine is a method or not.
### set\_is\_method($bool)
Setter for `is_method`.
### parameters
Parameters object of [Sub::Meta::Parameters](
https://metacpan.org/pod/Sub%3A%3AMeta%3A%3AParameters).
### set\_parameters($parameters)
Sets the parameters object of [Sub::Meta::Parameters](
https://metacpan.org/pod/Sub%3A%3AMeta%3A%3AParameters).
```perl
my $meta = Sub::Meta->new;
$meta->set_parameters(args => ['Str']);
$meta->parameters; # => Sub::Meta::Parameters->new(args => ['Str']);
# or
$meta->set_parameters(Sub::Meta::Parameters->new(args => ['Str']));
# alias
$meta->set_args(['Str']);
```
### args
The alias of `parameters.args`.
### set\_args($args)
The alias of `parameters.set_args`.
### nshift
The alias of `parameters.nshift`.
### set\_nshift($nshift)
The alias of `parameters.set_nshift`.
### slurpy
The alias of `parameters.slurpy`.
### set\_slurpy($slurpy)
The alias of `parameters.set_slurpy`.
### returns
Returns object of [Sub::Meta::Returns](
https://metacpan.org/pod/Sub%3A%3AMeta%3A%3AReturns).
### set\_returns($returns)
Sets the returns object of [Sub::Meta::Returns](
https://metacpan.org/pod/Sub%3A%3AMeta%3A%3AReturns) or any object.
```perl
my $meta = Sub::Meta->new;
$meta->set_returns({ type => 'Type'});
$meta->returns; # => Sub::Meta::Returns->new({type => 'Type'});
# or
$meta->set_returns(Sub::Meta::Returns->new(type => 'Foo'));
$meta->set_returns(MyReturns->new)
```
## OTHERS
### is\_same\_interface($other\_meta)
A boolean value indicating whether the subroutine's interface is same or not.
Specifically, check whether `subname`, `is_method`, `parameters` and `returns` are equal.
### is\_same\_interface\_inlined($other\_meta\_inlined)
Returns inlined `is_same_interface` string:
```perl
use Sub::Meta;
my $meta = Sub::Meta->new(subname => 'hello');
my $inline = $meta->is_same_interface_inlined('$_[0]');
# $inline looks like this:
# Scalar::Util::blessed($_[0]) && $_[0]->isa('Sub::Meta')
# && defined $_[0]->subname && 'hello' eq $_[0]->subname
# && !$_[0]->is_method
# && !$_[0]->parameters
# && !$_[0]->returns
my $check = eval "sub { $inline }";
$check->(Sub::Meta->new(subname => 'hello')); # => OK
$check->(Sub::Meta->new(subname => 'world')); # => NG
```
### parameters\_class
Returns class name of parameters. default: Sub::Meta::Parameters
Please override for customization.
### returns\_class
Returns class name of returns. default: Sub::Meta::Returns
Please override for customization.
# NOTE
## setter
You can set meta information of subroutine. `set_xxx` sets `xxx` and does not affect subroutine reference. On the other hands, `apply_xxx` sets `xxx` and apply `xxx` to subroutine reference.
Setter methods of `Sub::Meta` returns meta object. So you can chain setting:
```perl
$meta->set_subname('foo')
->set_stashname('Some')
```
## Pure-Perl version
By default `Sub::Meta` tries to load an XS implementation for speed.
If that fails, or if the environment variable `PERL_SUB_META_PP` is defined to a true value, it will fall back to a pure perl implementation.
# SEE ALSO
[Sub::Identify](
https://metacpan.org/pod/Sub%3A%3AIdentify), [Sub::Util](
https://metacpan.org/pod/Sub%3A%3AUtil), [Sub::Info](
https://metacpan.org/pod/Sub%3A%3AInfo), [Function::Paramters::Info](
https://metacpan.org/pod/Function%3A%3AParamters%3A%3AInfo), [Function::Return::Info](
https://metacpan.org/pod/Function%3A%3AReturn%3A%3AInfo)
# LICENSE
Copyright (C) kfly8.
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
# AUTHOR
kfly8 <
[email protected]>