{"id":15019226,"url":"https://github.com/kfly8/p5-sub-meta","last_synced_at":"2026-01-16T12:36:26.611Z","repository":{"id":34982572,"uuid":"193218438","full_name":"kfly8/p5-Sub-Meta","owner":"kfly8","description":"handle subroutine meta information","archived":false,"fork":false,"pushed_at":"2022-06-07T02:47:58.000Z","size":321,"stargazers_count":3,"open_issues_count":1,"forks_count":0,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-02-10T10:53:03.433Z","etag":null,"topics":["perl","perl5","perl5-module"],"latest_commit_sha":null,"homepage":"","language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kfly8.png","metadata":{"files":{"readme":"README.md","changelog":"Changes","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-06-22T09:57:06.000Z","updated_at":"2023-04-14T23:43:54.000Z","dependencies_parsed_at":"2022-09-13T08:41:55.281Z","dependency_job_id":null,"html_url":"https://github.com/kfly8/p5-Sub-Meta","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kfly8%2Fp5-Sub-Meta","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kfly8%2Fp5-Sub-Meta/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kfly8%2Fp5-Sub-Meta/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kfly8%2Fp5-Sub-Meta/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kfly8","download_url":"https://codeload.github.com/kfly8/p5-Sub-Meta/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247280176,"owners_count":20912965,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["perl","perl5","perl5-module"],"created_at":"2024-09-24T19:53:11.544Z","updated_at":"2026-01-16T12:36:21.579Z","avatar_url":"https://github.com/kfly8.png","language":"Perl","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Actions Status](https://github.com/kfly8/p5-Sub-Meta/workflows/test/badge.svg)](https://github.com/kfly8/p5-Sub-Meta/actions) [![Coverage Status](https://img.shields.io/coveralls/kfly8/p5-Sub-Meta/main.svg?style=flat)](https://coveralls.io/r/kfly8/p5-Sub-Meta?branch=main) [![MetaCPAN Release](https://badge.fury.io/pl/Sub-Meta.svg)](https://metacpan.org/release/Sub-Meta)\n# NAME\n\nSub::Meta - handle subroutine meta information\n\n# SYNOPSIS\n\n```perl\nuse Sub::Meta;\n\nsub hello($) :method { }\nmy $meta = Sub::Meta-\u003enew(sub =\u003e \\\u0026hello);\n$meta-\u003esubname; # =\u003e hello\n\n$meta-\u003esub;        # \\\u0026hello\n$meta-\u003esubname;    # hello\n$meta-\u003efullname    # main::hello\n$meta-\u003estashname   # main\n$meta-\u003efile        # path/to/file.pl\n$meta-\u003eline        # 5\n$meta-\u003eis_constant # !!0\n$meta-\u003eprototype   # $\n$meta-\u003eattribute   # ['method']\n$meta-\u003eis_method   # undef\n$meta-\u003eparameters  # undef\n$meta-\u003ereturns     # undef\n$meta-\u003edisplay     # 'sub hello'\n\n# setter\n$meta-\u003eset_subname('world');\n$meta-\u003esubname; # world\n$meta-\u003efullname; # main::world\n\n# apply to sub\n$meta-\u003eapply_prototype('$@');\n$meta-\u003eprototype; # $@\nSub::Util::prototype($meta-\u003esub); # $@\n```\n\nAnd 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).\n\n```perl\n$meta-\u003eset_parameters(args =\u003e ['Str']));\n$meta-\u003eparameters-\u003eargs; # [ Sub::Meta::Param-\u003enew({ type =\u003e 'Str' }) ]\n\n$meta-\u003eset_args(['Str']);\n$meta-\u003eargs; # [ Sub::Meta::Param-\u003enew({ type =\u003e 'Str' }) ]\n\n$meta-\u003eset_returns('Str');\n$meta-\u003ereturns-\u003escalar; # 'Str'\n$meta-\u003ereturns-\u003elist;   # 'Str'\n```\n\nAnd you can compare meta informations:\n\n```perl\nmy $other = Sub::Meta-\u003enew(subname =\u003e 'hello');\n$meta-\u003eis_same_interface($other); # 1\n$meta eq $other; # 1\n```\n\n# DESCRIPTION\n\n`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.\n\n# METHODS\n\n## new\n\nConstructor of `Sub::Meta`.\n\n```perl\nuse Sub::Meta;\nuse Types::Standard -types;\n\n# sub Greeting::hello(Str) -\u003e Str\nSub::Meta-\u003enew(\n    fullname    =\u003e 'Greeting::hello',\n    is_constant =\u003e 0,\n    prototype   =\u003e '$',\n    attribute   =\u003e ['method'],\n    is_method   =\u003e 1,\n    parameters  =\u003e { args =\u003e [{ type =\u003e Str }]},\n    returns     =\u003e Str,\n);\n```\n\nOthers are as follows:\n\n```perl\n# sub add(Int, Int) -\u003e Int\nSub::Meta-\u003enew(\n    subname =\u003e 'add',\n    args    =\u003e [Int, Int],\n    returns =\u003e Int,\n);\n\n# method hello(Str) -\u003e Str\nSub::Meta-\u003enew(\n    subname   =\u003e 'hello',\n    args      =\u003e [{ message =\u003e Str }],\n    is_method =\u003e 1,\n    returns   =\u003e Str,\n);\n\n# sub twice(@numbers) -\u003e ArrayRef[Int]\nSub::Meta-\u003enew(\n    subname   =\u003e 'twice',\n    args      =\u003e [],\n    slurpy    =\u003e { name =\u003e '@numbers' },\n    returns   =\u003e ArrayRef[Int],\n);\n\n# Named parameters:\n# sub foo(Str :a) -\u003e Str\nSub::Meta-\u003enew(\n    subname   =\u003e 'foo',\n    args      =\u003e { a =\u003e Str },\n    returns   =\u003e Str,\n);\n\n# is equivalent to\nSub::Meta-\u003enew(\n    subname   =\u003e 'foo',\n    args      =\u003e [{ name =\u003e 'a', isa =\u003e Str, named =\u003e 1 }],\n    returns   =\u003e Str,\n);\n```\n\nAnother way to create a Sub::Meta is to use [Sub::Meta::Creator](https://metacpan.org/pod/Sub%3A%3AMeta%3A%3ACreator):\n\n```perl\nuse Sub::Meta::Creator;\nuse Sub::Meta::Finder::FunctionParameters;\n\nmy $creator = Sub::Meta::Creator-\u003enew(\n    finders =\u003e [ \\\u0026Sub::Meta::Finder::FunctionParameters::find_materials ],\n);\n\nuse Function::Parameters;\nuse Types::Standard -types;\n\nmethod hello(Str $msg) { }\nmy $meta = $creator-\u003ecreate(\\\u0026hello);\n# =\u003e\n# Sub::Meta\n#   args [\n#       [0] Sub::Meta::Param-\u003enew(name =\u003e '$msg', type =\u003e Str)\n#   ],\n#   invocant   Sub::Meta::Param-\u003e(name =\u003e '$self', invocant =\u003e 1),\n#   nshift     1,\n#   slurpy     !!0\n```\n\n## ACCESSORS\n\n### sub\n\nAccessor for subroutine.\n\n- `sub`\n\n    ```perl\n    method sub() =\u003e Maybe[CodeRef]\n    ```\n\n    Return a subroutine.\n\n- `has_sub`\n\n    ```perl\n    method has_sub() =\u003e Bool\n    ```\n\n    Whether Sub::Meta has subroutine or not.\n\n- `set_sub($sub)`\n\n    ```perl\n    method set_sub(CodeRef $sub) =\u003e $self\n    ```\n\n    Setter for subroutine.\n\n    ```perl\n    sub hello { ... }\n    $meta-\u003eset_sub(\\\u0026hello);\n    $meta-\u003esub # =\u003e \\\u0026hello\n\n    # And set subname, stashname\n    $meta-\u003esubname; # hello\n    $meta-\u003estashname; # main\n    ```\n\n### subname\n\nAccessor for subroutine name\n\n- `subname`\n\n    ```perl\n    method subname() =\u003e Str\n    ```\n\n- `has_subname`\n\n    ```perl\n    method has_subname() =\u003e Bool\n    ```\n\n    Whether Sub::Meta has subroutine name or not.\n\n- `set_subname($subname)`\n\n    ```perl\n    method set_subname(Str $subname) =\u003e $self\n    ```\n\n    Setter for subroutine name.\n\n    ```perl\n    $meta-\u003esubname; # hello\n    $meta-\u003eset_subname('world');\n    $meta-\u003esubname; # world\n    Sub::Util::subname($meta-\u003esub); # hello (NOT apply to sub)\n    ```\n\n- `apply_subname($subname)`\n\n    ```perl\n    method apply_subname(Str $subname) =\u003e $self\n    ```\n\n    Sets subroutine name and apply to the subroutine reference.\n\n    ```perl\n    $meta-\u003esubname; # hello\n    $meta-\u003eapply_subname('world');\n    $meta-\u003esubname; # world\n    Sub::Util::subname($meta-\u003esub); # world\n    ```\n\n### fullname\n\nAccessor for subroutine full name\n\n- `fullname`\n\n    ```perl\n    method fullname() =\u003e Str\n    ```\n\n    A subroutine full name, e.g. `main::hello`\n\n- `has_fullname`\n\n    ```perl\n    method has_fullname() =\u003e Bool\n    ```\n\n    Whether Sub::Meta has subroutine full name or not.\n\n- `set_fullname($fullname)`\n\n    ```perl\n    method set_fullname(Str $fullname) =\u003e $self\n    ```\n\n    Setter for subroutine full name.\n\n### stashname\n\nAccessor for subroutine stash name\n\n- `stashname`\n\n    ```perl\n    method stashname() =\u003e Str\n    ```\n\n    A subroutine stash name, e.g. `main`\n\n- `has_stashname`\n\n    ```perl\n    method has_stashname() =\u003e Bool\n    ```\n\n    Whether Sub::Meta has subroutine stash name or not.\n\n- `set_stashname($stashname)`\n\n    ```perl\n    method set_stashname(Str $stashname) =\u003e $self\n    ```\n\n    Setter for subroutine stash name.\n\n### subinfo\n\nAccessor for subroutine information\n\n- `subinfo`\n\n    ```perl\n    method subinfo() =\u003e Tuple[Str,Str]\n    ```\n\n    A subroutine information, e.g. `['main', 'hello']`\n\n- `set_subinfo([$stashname, $subname])`\n\n    ```perl\n    method set_stashname(Tuple[Str $stashname, Str $subname]) =\u003e $self\n    ```\n\n    Setter for subroutine information.\n\n### file, line\n\nAccessor for filename and line where subroutine is defined\n\n- `file`\n\n    ```perl\n    method file() =\u003e Maybe[Str]\n    ```\n\n    A filename where subroutine is defined, e.g. `path/to/main.pl`.\n\n- `has_file`\n\n    ```perl\n    method has_file() =\u003e Bool\n    ```\n\n    Whether Sub::Meta has a filename where subroutine is defined.\n\n- `set_file($filepath)`\n\n    ```perl\n    method set_file(Str $filepath) =\u003e $self\n    ```\n\n    Setter for `file`.\n\n- `line`\n\n    ```perl\n    method line() =\u003e Maybe[Int]\n    ```\n\n    A line where the definition of subroutine started, e.g. `5`\n\n- `has_line`\n\n    ```perl\n    method has_line() =\u003e Bool\n    ```\n\n    Whether Sub::Meta has a line where the definition of subroutine started.\n\n- `set_line($line)`\n\n    ```perl\n    method set_line(Int $line) =\u003e $self\n    ```\n\n    Setter for `line`.\n\n### is\\_constant\n\n- `is_constant`\n\n    ```perl\n    method is_constant() =\u003e Maybe[Bool]\n    ```\n\n    If the subroutine is set, it returns whether it is a constant or not, if not set, it returns undef.\n\n- `set_is_constant($bool)`\n\n    ```perl\n    method set_is_constant(Bool $bool) =\u003e $self\n    ```\n\n    Setter for `is_constant`.\n\n### prototype\n\nAccessor for prototype of subroutine reference.\n\n- `prototype`\n\n    ```perl\n    method prototype() =\u003e Maybe[Str]\n    ```\n\n    If the subroutine is set, it returns a prototype of subroutine, if not set, it returns undef.\n    e.g. `$@`\n\n- `has_prototype`\n\n    ```perl\n    method has_prototype() =\u003e Bool\n    ```\n\n    Whether Sub::Meta has prototype or not.\n\n- `set_prototype($prototype)`\n\n    ```perl\n    method set_prototype(Str $prototype) =\u003e $self\n    ```\n\n    Setter for `prototype`.\n\n- `apply_prototype($prototype)`\n\n    ```perl\n    method apply_prototype(Str $prototype) =\u003e $self\n    ```\n\n    Sets subroutine prototype and apply to the subroutine reference.\n\n### attribute\n\nAccessor for attribute of subroutine reference.\n\n- `attribute`\n\n    ```perl\n    method attribute() =\u003e Maybe[ArrayRef[Str]]\n    ```\n\n    If the subroutine is set, it returns a attribute of subroutine, if not set, it returns undef.\n    e.g. `['method']`, `undef`\n\n- `has_attribute`\n\n    ```perl\n    method has_attribute() =\u003e Bool\n    ```\n\n    Whether Sub::Meta has attribute or not.\n\n- `set_attribute($attribute)`\n\n    ```perl\n    method set_attribute(ArrayRef[Str] $attribute) =\u003e $self\n    ```\n\n    Setter for `attribute`.\n\n- `apply_attribute(@attribute)`\n\n    ```perl\n    method apply_attribute(Str @attribute) =\u003e $self\n    ```\n\n    Sets subroutine attributes and apply to the subroutine reference.\n\n### is\\_method\n\n- `is_method`\n\n    ```perl\n    method is_method() =\u003e Bool\n    ```\n\n    Whether the subroutine is a method or not.\n\n- `set_is_method($bool)`\n\n    ```perl\n    method set_is_method(Bool $bool) =\u003e Bool\n    ```\n\n    Setter for `is_method`.\n\n### parameters\n\nAccessor for parameters object of [Sub::Meta::Parameters](https://metacpan.org/pod/Sub%3A%3AMeta%3A%3AParameters)\n\n- `parameters`\n\n    ```perl\n    method parameters() =\u003e InstanceOf[Sub::Meta::Parameters]\n    ```\n\n    If the parameters is set, it returns the parameters object.\n\n- `set_parameters($parameters)`\n\n    ```perl\n    method set_parameters(InstanceOf[Sub::Meta::Parameters] $parameters) =\u003e $self\n    method set_parameters(@sub_meta_parameters_args) =\u003e $self\n    ```\n\n    Sets the parameters object of [Sub::Meta::Parameters](https://metacpan.org/pod/Sub%3A%3AMeta%3A%3AParameters).\n\n    ```perl\n    my $meta = Sub::Meta-\u003enew;\n\n    my $parameters = Sub::Meta::Parameters-\u003enew(args =\u003e ['Str']);\n    $meta-\u003eset_parameters($parameters);\n\n    # or\n    $meta-\u003eset_parameters(args =\u003e ['Str']);\n    $meta-\u003eparameters; # =\u003e Sub::Meta::Parameters-\u003enew(args =\u003e ['Str']);\n\n    # alias\n    $meta-\u003eset_args(['Str']);\n    ```\n\n- `args`\n\n    The alias of `parameters.args`.\n\n- `set_args($args)`\n\n    The alias of `parameters.set_args`.\n\n- `all_args`\n\n    The alias of `parameters.all_args`.\n\n- `nshift`\n\n    The alias of `parameters.nshift`.\n\n- `set_nshift($nshift)`\n\n    The alias of `parameters.set_nshift`.\n\n- `invocant`\n\n    The alias of `parameters.invocant`.\n\n- `invocants`\n\n    The alias of `parameters.invocants`.\n\n- `set_invocant($invocant)`\n\n    The alias of `parameters.set_invocant`.\n\n- `slurpy`\n\n    The alias of `parameters.slurpy`.\n\n- `set_slurpy($slurpy)`\n\n    The alias of `parameters.set_slurpy`.\n\n### returns\n\nAccessor for returns object of [Sub::Meta::Returns](https://metacpan.org/pod/Sub%3A%3AMeta%3A%3AReturns)\n\n- `returns`\n\n    ```perl\n    method returns() =\u003e InstanceOf[Sub::Meta::Returns]\n    ```\n\n    If the returns is set, it returns the returns object.\n\n- `set_returns($returns)`\n\n    ```perl\n    method set_returns(InstanceOf[Sub::Meta::Returns] $returns) =\u003e $self\n    method set_returns(@sub_meta_returns_args) =\u003e $self\n    ```\n\n    Sets the returns object of [Sub::Meta::Returns](https://metacpan.org/pod/Sub%3A%3AMeta%3A%3AReturns) or any object.\n\n    ```perl\n    my $meta = Sub::Meta-\u003enew;\n    $meta-\u003eset_returns({ type =\u003e 'Type'});\n    $meta-\u003ereturns; # =\u003e Sub::Meta::Returns-\u003enew({type =\u003e 'Type'});\n\n    # or\n    $meta-\u003eset_returns(Sub::Meta::Returns-\u003enew(type =\u003e 'Foo'));\n    $meta-\u003eset_returns(MyReturns-\u003enew)\n    ```\n\n## METHODS\n\n### apply\\_meta($other\\_meta)\n\n```perl\nmethod apply_meta(InstanceOf[Sub::Meta] $other_meta) =\u003e $self\n```\n\nApply subroutine subname, prototype and attributes of `$other_meta`.\n\n### is\\_same\\_interface($other\\_meta)\n\n```perl\nmethod is_same_interface(InstanceOf[Sub::Meta] $other_meta) =\u003e Bool\n```\n\nA boolean value indicating whether the subroutine's interface is same or not.\nSpecifically, check whether `subname`, `is_method`, `parameters` and `returns` are equal.\n\n### is\\_strict\\_same\\_interface($other\\_meta)\n\nAlias for `is_same_interface`\n\n### is\\_relaxed\\_same\\_interface($other\\_meta)\n\n```perl\nmethod is_relaxed_same_interface(InstanceOf[Sub::Meta] $other_meta) =\u003e Bool\n```\n\nA boolean value indicating whether the subroutine's interface is relaxed same or not.\nSpecifically, check whether `subname`, `is_method`, `parameters` and `returns` satisfy\nthe condition of `$self` side.\n\n#### Difference between `strict` and `relaxed`\n\nIf it is `is_relaxed_same_interface` method, the conditions can be many.\nFor example, the number of arguments can be many.\nThe following code is a test to show the difference between strict and relaxed.\n\n```perl\nmy @tests = (\n    {},                { subname =\u003e 'foo' },\n    {},                { args =\u003e [Int] },\n    { args =\u003e [Int] }, { args =\u003e [Int, Str] },\n    { args =\u003e [Int] }, { args =\u003e [Int], slurpy =\u003e Str },\n    { args =\u003e [Int] }, { args =\u003e [{ type =\u003e Int, name =\u003e '$a' }] },\n    {},                { returns =\u003e Int },\n    { returns =\u003e { scalar =\u003e Int } }, { returns =\u003e { scalar =\u003e Int, list =\u003e Int } },\n);\n\nwhile (@tests) {\n    my ($a, $b) = splice @tests, 0, 2;\n    my $meta = Sub::Meta-\u003enew($a);\n    my $other = Sub::Meta-\u003enew($b);\n\n    ok !$meta-\u003eis_strict_same_interface($other);\n    ok $meta-\u003eis_relaxed_same_interface($other);\n}\n```\n\n### is\\_same\\_interface\\_inlined($other\\_meta\\_inlined)\n\n```perl\nmethod is_same_interface_inlined(InstanceOf[Sub::Meta] $other_meta) =\u003e Str\n```\n\n### is\\_strict\\_same\\_interface\\_inlined($other\\_meta)\n\nAlias for `is_same_interface_inlined`\n\nReturns inlined `is_same_interface` string:\n\n```perl\nuse Sub::Meta;\nmy $meta = Sub::Meta-\u003enew(subname =\u003e 'hello');\nmy $inline = $meta-\u003eis_same_interface_inlined('$_[0]');\n# $inline looks like this:\n#    Scalar::Util::blessed($_[0]) \u0026\u0026 $_[0]-\u003eisa('Sub::Meta')\n#    \u0026\u0026 defined $_[0]-\u003esubname \u0026\u0026 'hello' eq $_[0]-\u003esubname\n#    \u0026\u0026 !$_[0]-\u003eis_method\n#    \u0026\u0026 !$_[0]-\u003eparameters\n#    \u0026\u0026 !$_[0]-\u003ereturns\nmy $check = eval \"sub { $inline }\";\n$check-\u003e(Sub::Meta-\u003enew(subname =\u003e 'hello')); # =\u003e OK\n$check-\u003e(Sub::Meta-\u003enew(subname =\u003e 'world')); # =\u003e NG\n```\n\n### is\\_relaxed\\_same\\_interface\\_inlined($other\\_meta\\_inlined)\n\n```perl\nmethod is_relaxed_same_interface_inlined(InstanceOf[Sub::Meta] $other_meta) =\u003e Str\n```\n\nReturns inlined `is_relaxed_same_interface` string.\n\n### error\\_message($other\\_meta)\n\n```perl\nmethod error_message(InstanceOf[Sub::Meta] $other_meta) =\u003e Str\n```\n\nReturn the error message when the interface is not same. If same, then return empty string\n\n### relaxed\\_error\\_message($other\\_meta)\n\n```perl\nmethod relaxed_error_message(InstanceOf[Sub::Meta] $other_meta) =\u003e Str\n```\n\nReturn the error message when the interface does not satisfy the `$self` meta. If match, then return empty string.\n\n### display\n\n```perl\nmethod display() =\u003e Str\n```\n\nReturns the display of Sub::Meta:\n\n```perl\nuse Sub::Meta;\nuse Types::Standard qw(Str);\nmy $meta = Sub::Meta-\u003enew(\n    subname =\u003e 'hello',\n    is_method =\u003e 1,\n    args =\u003e [Str],\n    returns =\u003e Str,\n);\n$meta-\u003edisplay;  # 'method hello(Str) =\u003e Str'\n```\n\n## OTHERS\n\n### parameters\\_class\n\n```perl\nmethod parameters_class() =\u003e Str\n```\n\nReturns class name of parameters. default: Sub::Meta::Parameters\nPlease override for customization.\n\n### returns\\_class\n\n```perl\nmethod returns_class() =\u003e Str\n```\n\nReturns class name of returns. default: Sub::Meta::Returns\nPlease override for customization.\n\n# NOTE\n\n## setter\n\nYou 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.\n\nSetter methods of `Sub::Meta` returns meta object. So you can chain setting:\n\n```perl\n$meta-\u003eset_subname('foo')\n     -\u003eset_stashname('Some')\n```\n\n## Pure-Perl version\n\nBy default `Sub::Meta` tries to load an XS implementation for speed.\nIf 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.\n\n# SEE ALSO\n\n[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)\n\n# LICENSE\n\nCopyright (C) kfly8.\n\nThis library is free software; you can redistribute it and/or modify\nit under the same terms as Perl itself.\n\n# AUTHOR\n\nkfly8 \u003ckfly@cpan.org\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkfly8%2Fp5-sub-meta","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkfly8%2Fp5-sub-meta","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkfly8%2Fp5-sub-meta/lists"}