version 1.0202
[p5sagit/Function-Parameters.git] / lib / Function / Parameters / Info.pm
CommitLineData
53c979f0 1package Function::Parameters::Info;
2
3use v5.14.0;
53c979f0 4use warnings;
5
ff265988 6our $VERSION = '1.0202';
53c979f0 7
8c4ca548 8# If Moo isn't loaded yet but Moose is, avoid pulling in Moo and fall back to Moose
1f8c776e 9my ($Moo, $meta_make_immutable);
8c4ca548 10BEGIN {
11 if ($INC{'Moose.pm'} && !$INC{'Moo.pm'}) {
12 $Moo = 'Moose';
1f8c776e 13 $meta_make_immutable = sub { $_[0]->meta->make_immutable };
8c4ca548 14 } else {
15 require Moo;
16 $Moo = 'Moo';
1f8c776e 17 $meta_make_immutable = sub {};
8c4ca548 18 }
19 $Moo->import;
20}
21
51a483f8 22{
23 package Function::Parameters::Param;
24
8c4ca548 25 BEGIN { $Moo->import; }
51a483f8 26 use overload
27 fallback => 1,
11c807bc 28 '""' => sub { $_[0]->name },
51a483f8 29 ;
30
31 has $_ => (is => 'ro') for qw(name type);
8c4ca548 32
1f8c776e 33 __PACKAGE__->$meta_make_immutable;
51a483f8 34}
35
53c979f0 36my @pn_ro = glob '{positional,named}_{required,optional}';
37
38for my $attr (qw[keyword invocant slurpy], map "_$_", @pn_ro) {
39 has $attr => (
40 is => 'ro',
41 );
42}
43
44for my $gen (join "\n", map "sub $_ { \@{\$_[0]->_$_} }", @pn_ro) {
45 eval "$gen\n1" or die $@;
46}
47
ebdc721b 48sub args_min {
49 my $self = shift;
50 my $r = 0;
51 $r++ if defined $self->invocant;
52 $r += $self->positional_required;
53 $r += $self->named_required * 2;
54 $r
55}
56
57sub args_max {
58 my $self = shift;
59 return 0 + 'Inf' if defined $self->slurpy || $self->named_required || $self->named_optional;
60 my $r = 0;
61 $r++ if defined $self->invocant;
62 $r += $self->positional_required;
63 $r += $self->positional_optional;
64 $r
65}
66
1f8c776e 67__PACKAGE__->$meta_make_immutable;
8c4ca548 68
53c979f0 69'ok'
70
71__END__
ebdc721b 72
73=encoding UTF-8
74
75=head1 NAME
76
77Function::Parameters::Info - Information about parameter lists
78
79=head1 SYNOPSIS
80
81 use Function::Parameters;
82
83 fun foo($x, $y, :$hello, :$world = undef) {}
84
85 my $info = Function::Parameters::info \&foo;
86 my $p0 = $info->invocant; # undef
87 my @p1 = $info->positional_required; # ('$x', '$y')
88 my @p2 = $info->positional_optional; # ()
89 my @p3 = $info->named_required; # ('$hello')
90 my @p4 = $info->named_optional; # ('$world')
91 my $p5 = $info->slurpy; # undef
92 my $min = $info->args_min; # 4
93 my $max = $info->args_max; # inf
94
95 my $invocant = Function::Parameters::info(method () { 42 })->invocant; # '$self'
96
97 my $slurpy = Function::Parameters::info(fun {})->slurpy; # '@_'
98
99=head1 DESCRIPTION
100
101L<C<Function::Parameters::info>|Function::Parameters/Introspection> returns
102objects of this class to describe parameter lists of functions. The following
103methods are available:
104
0d87c016 105=head2 $info->invocant
ebdc721b 106
107Returns the name of the variable into which the first argument is
420e3b82 108L<C<shift>|perlfunc/shift>ed automatically, or C<undef> if no such thing
ebdc721b 109exists. This will usually return C<'$self'> for methods.
110
0d87c016 111=head2 $info->positional_required
ebdc721b 112
113Returns a list of the names of the required positional parameters (or a count
114in scalar context).
115
0d87c016 116=head2 $info->positional_optional
ebdc721b 117
118Returns a list of the names of the optional positional parameters (or a count
119in scalar context).
120
0d87c016 121=head2 $info->named_required
ebdc721b 122
123Returns a list of the names of the required named parameters (or a count
124in scalar context).
125
0d87c016 126=head2 $info->named_optional
ebdc721b 127
128Returns a list of the names of the optional named parameters (or a count
129in scalar context).
130
0d87c016 131=head2 $info->slurpy
ebdc721b 132
133Returns the name of the final array or hash that gobbles up all remaining
134arguments, or C<undef> if no such thing exists.
135
136As a special case, functions defined without an explicit parameter list (i.e.
137without C<( )>) will return C<'@_'> here because they accept any number of
138arguments.
139
0d87c016 140=head2 $info->args_min
ebdc721b 141
142Returns the minimum number of arguments this function requires. This is
143computed as follows: Invocant and required positional parameters count 1 each.
144Optional parameters don't count. Required named parameters count 2 each (key +
145value). Slurpy parameters don't count either because they accept empty lists.
146
0d87c016 147=head2 $info->args_max
ebdc721b 148
149Returns the maximum number of arguments this function accepts. This is computed
150as follows: If there is any named or slurpy parameter, the result is C<Inf>.
151Otherwise the result is the sum of all invocant and positional parameters.
152
0175ff9a 153=head2 Experimental feature: Types
154
155All the methods described above actually return parameter objects wherever the
156description says "name". These objects have two methods: C<name>, which
157returns the name of the parameter (as a plain string), and C<type>, which
158returns the corresponding type constraint object (or undef if there was no type
159specified).
160
161This should be invisible if you don't use types because the objects also
162L<overload|overload> stringification to call C<name>. That is, if you treat
163parameter objects like strings, they behave like strings (i.e. their names).
164
ebdc721b 165=head1 SEE ALSO
166
167L<Function::Parameters>
168
169=head1 AUTHOR
170
171Lukas Mai, C<< <l.mai at web.de> >>
172
173=head1 COPYRIGHT & LICENSE
174
ea89928a 175Copyright 2013 Lukas Mai.
ebdc721b 176
177This program is free software; you can redistribute it and/or modify it
178under the terms of either: the GNU General Public License as published
179by the Free Software Foundation; or the Artistic License.
180
181See http://dev.perl.org/licenses/ for more information.
182
183=cut