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