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