formatting and stuff
[p5sagit/Function-Parameters.git] / lib / Function / Parameters.pm
1 package Function::Parameters;
2
3 use v5.14.0;
4 use warnings;
5
6 use Carp qw(confess);
7
8 use XSLoader;
9 BEGIN {
10         our $VERSION = '1.0103_01';
11         our $XS_VERSION = $VERSION;
12         $VERSION = eval $VERSION;
13         XSLoader::load;
14 }
15
16 sub _assert_valid_identifier {
17         my ($name, $with_dollar) = @_;
18         my $bonus = $with_dollar ? '\$' : '';
19         $name =~ /^${bonus}[^\W\d]\w*\z/
20                 or confess qq{"$name" doesn't look like a valid identifier};
21 }
22
23 sub _assert_valid_attributes {
24         my ($attrs) = @_;
25         $attrs =~ m{
26                 ^ \s*+
27                 : \s*+
28                 (?&ident) (?! [^\s:(] ) (?&param)?+ \s*+
29                 (?:
30                         (?: : \s*+ )?
31                         (?&ident) (?! [^\s:(] ) (?&param)?+ \s*+
32                 )*+
33                 \z
34
35                 (?(DEFINE)
36                         (?<ident>
37                                 [^\W\d]
38                                 \w*+
39                         )
40                         (?<param>
41                                 \(
42                                 [^()\\]*+
43                                 (?:
44                                         (?:
45                                                 \\ .
46                                         |
47                                                 (?&param)
48                                         )
49                                         [^()\\]*+
50                                 )*+
51                                 \)
52                         )
53                 )
54         }sx or confess qq{"$attrs" doesn't look like valid attributes};
55 }
56
57 my @bare_arms = qw(function method);
58 my %type_map = (
59         function    => {
60                 name                 => 'optional',
61                 default_arguments    => 1,
62                 check_argument_count => 0,
63                 named_parameters     => 1,
64                 types                => 1,
65         },
66         method      => {
67                 name                 => 'optional',
68                 default_arguments    => 1,
69                 check_argument_count => 0,
70                 named_parameters     => 1,
71                 types                => 1,
72                 attrs                => ':method',
73                 shift                => '$self',
74                 invocant             => 1,
75         },
76         classmethod => {
77                 name                 => 'optional',
78                 default_arguments    => 1,
79                 check_argument_count => 0,
80                 named_parameters     => 1,
81                 types                => 1,
82                 attributes           => ':method',
83                 shift                => '$class',
84                 invocant             => 1,
85         },
86 );
87 for my $k (keys %type_map) {
88         $type_map{$k . '_strict'} = {
89                 %{$type_map{$k}},
90                 check_argument_count => 1,
91         };
92 }
93
94 sub import {
95         my $class = shift;
96
97         if (!@_) {
98                 @_ = {
99                         fun => 'function',
100                         method => 'method',
101                 };
102         }
103         if (@_ == 1 && $_[0] eq ':strict') {
104                 @_ = {
105                         fun => 'function_strict',
106                         method => 'method_strict',
107                 };
108         }
109         if (@_ == 1 && ref($_[0]) eq 'HASH') {
110                 @_ = map [$_, $_[0]{$_}], keys %{$_[0]};
111         }
112
113         my %spec;
114
115         my $bare = 0;
116         for my $proto (@_) {
117                 my $item = ref $proto
118                         ? $proto
119                         : [$proto, $bare_arms[$bare++] || confess(qq{Don't know what to do with "$proto"})]
120                 ;
121                 my ($name, $proto_type) = @$item;
122                 _assert_valid_identifier $name;
123
124                 unless (ref $proto_type) {
125                         # use '||' instead of 'or' to preserve $proto_type in the error message
126                         $proto_type = $type_map{$proto_type}
127                                 || confess qq["$proto_type" doesn't look like a valid type (one of ${\join ', ', sort keys %type_map})];
128                 }
129
130                 my %type = %$proto_type;
131                 my %clean;
132
133                 $clean{name} = delete $type{name} || 'optional';
134                 $clean{name} =~ /^(?:optional|required|prohibited)\z/
135                         or confess qq["$clean{name}" doesn't look like a valid name attribute (one of optional, required, prohibited)];
136
137                 $clean{shift} = delete $type{shift} || '';
138                 _assert_valid_identifier $clean{shift}, 1 if $clean{shift};
139
140                 $clean{attrs} = join ' ', map delete $type{$_} || (), qw(attributes attrs);
141                 _assert_valid_attributes $clean{attrs} if $clean{attrs};
142                 
143                 $clean{default_arguments} =
144                         exists $type{default_arguments}
145                         ? !!delete $type{default_arguments}
146                         : 1
147                 ;
148                 $clean{check_argument_count} = !!delete $type{check_argument_count};
149                 $clean{invocant} = !!delete $type{invocant};
150                 $clean{named_parameters} = !!delete $type{named_parameters};
151                 $clean{types} = !!delete $type{types};
152
153                 %type and confess "Invalid keyword property: @{[keys %type]}";
154
155                 $spec{$name} = \%clean;
156         }
157         
158         for my $kw (keys %spec) {
159                 my $type = $spec{$kw};
160
161                 my $flags =
162                         $type->{name} eq 'prohibited' ? FLAG_ANON_OK                :
163                         $type->{name} eq 'required'   ? FLAG_NAME_OK                :
164                                                         FLAG_ANON_OK | FLAG_NAME_OK
165                 ;
166                 $flags |= FLAG_DEFAULT_ARGS                   if $type->{default_arguments};
167                 $flags |= FLAG_CHECK_NARGS | FLAG_CHECK_TARGS if $type->{check_argument_count};
168                 $flags |= FLAG_INVOCANT                       if $type->{invocant};
169                 $flags |= FLAG_NAMED_PARAMS                   if $type->{named_parameters};
170                 $flags |= FLAG_TYPES_OK                       if $type->{types};
171                 $^H{HINTK_FLAGS_ . $kw} = $flags;
172                 $^H{HINTK_SHIFT_ . $kw} = $type->{shift};
173                 $^H{HINTK_ATTRS_ . $kw} = $type->{attrs};
174                 $^H{+HINTK_KEYWORDS} .= "$kw ";
175         }
176 }
177
178 sub unimport {
179         my $class = shift;
180
181         if (!@_) {
182                 delete $^H{+HINTK_KEYWORDS};
183                 return;
184         }
185
186         for my $kw (@_) {
187                 $^H{+HINTK_KEYWORDS} =~ s/(?<![^ ])\Q$kw\E //g;
188         }
189 }
190
191
192 our %metadata;
193
194 sub _register_info {
195         my (
196                 $key,
197                 $declarator,
198                 $invocant,
199                 $invocant_type,
200                 $positional_required,
201                 $positional_optional,
202                 $named_required,
203                 $named_optional,
204                 $slurpy,
205                 $slurpy_type,
206         ) = @_;
207
208         my $info = {
209                 declarator => $declarator,
210                 invocant => defined $invocant ? [$invocant, $invocant_type] : undef,
211                 slurpy   => defined $slurpy   ? [$slurpy  , $slurpy_type  ] : undef,
212                 positional_required => $positional_required,
213                 positional_optional => $positional_optional,
214                 named_required => $named_required,
215                 named_optional => $named_optional,
216         };
217
218         $metadata{$key} = $info;
219 }
220
221 sub _mkparam1 {
222         my ($pair) = @_;
223         my ($v, $t) = @{$pair || []} or return undef;
224         Function::Parameters::Param->new(
225                 name => $v,
226                 type => $t,
227         )
228 }
229
230 sub _mkparams {
231         my @r;
232         while (my ($v, $t) = splice @_, 0, 2) {
233                 push @r, Function::Parameters::Param->new(
234                         name => $v,
235                         type => $t,
236                 );
237         }
238         \@r
239 }
240
241 sub info {
242         my ($func) = @_;
243         my $key = _cv_root $func or return undef;
244         my $info = $metadata{$key} or return undef;
245         require Function::Parameters::Info;
246         Function::Parameters::Info->new(
247                 keyword => $info->{declarator},
248                 invocant => _mkparam1($info->{invocant}),
249                 slurpy => _mkparam1($info->{slurpy}),
250                 (map +("_$_" => _mkparams @{$info->{$_}}), glob '{positional,named}_{required,optional}')
251         )
252 }
253
254 'ok'
255
256 __END__
257
258 =encoding UTF-8
259
260 =head1 NAME
261
262 Function::Parameters - subroutine definitions with parameter lists
263
264 =head1 SYNOPSIS
265
266  use Function::Parameters qw(:strict);
267  
268  # simple function
269  fun foo($bar, $baz) {
270    return $bar + $baz;
271  }
272  
273  # function with prototype
274  fun mymap($fun, @args)
275    :(&@)
276  {
277    my @res;
278    for (@args) {
279      push @res, $fun->($_);
280    }
281    @res
282  }
283  
284  print "$_\n" for mymap { $_ * 2 } 1 .. 4;
285  
286  # method with implicit $self
287  method set_name($name) {
288    $self->{name} = $name;
289  }
290  
291  # method with explicit invocant
292  method new($class: %init) {
293    return bless { %init }, $class;
294  }
295  
296  # function with optional parameters
297  fun search($haystack, $needle = qr/^(?!)/, $offset = 0) {
298    ...
299  }
300  
301  # method with named parameters
302  method resize(:$width, :$height) {
303    $self->{width}  = $width;
304    $self->{height} = $height;
305  }
306  
307  $obj->resize(height => 4, width => 5);
308  
309  # function with named optional parameters
310  fun search($haystack, :$needle = qr/^(?!)/, :$offset = 0) {
311    ...
312  }
313  
314  my $results = search $text, offset => 200;
315
316 =head1 DESCRIPTION
317
318 This module extends Perl with keywords that let you define functions with
319 parameter lists. It uses Perl's L<keyword plugin|perlapi/PL_keyword_plugin>
320 API, so it works reliably and doesn't require a source filter.
321
322 =head2 Basics
323
324 The anatomy of a function (as recognized by this module):
325
326 =over
327
328 =item 1.
329
330 The keyword introducing the function.
331
332 =item 2.
333
334 The function name (optional).
335
336 =item 3.
337
338 The parameter list (optional).
339
340 =item 4.
341
342 The prototype (optional).
343
344 =item 5.
345
346 The attribute list (optional).
347
348 =item 6.
349
350 The function body.
351
352 =back
353
354 Example:
355
356   # (1)   (2) (3)      (4)   (5)     (6)
357     fun   foo ($x, $y) :($$) :lvalue { ... }
358  
359   #         (1) (6)
360     my $f = fun { ... };
361
362 In the following section I'm going to describe all parts in order from simplest to most complex.
363
364 =head3 Body
365
366 This is just a normal block of statements, as with L<C<sub>|perlsub>. No surprises here.
367
368 =head3 Name
369
370 If present, it specifies the name of the function being defined. As with
371 L<C<sub>|perlsub>, if a name is present, the whole declaration is syntactically
372 a statement and its effects are performed at compile time (i.e. at runtime you
373 can call functions whose definitions only occur later in the file). If no name
374 is present, the declaration is an expression that evaluates to a reference to
375 the function in question. No surprises here either.
376
377 =head3 Attributes
378
379 Attributes are relatively unusual in Perl code, but if you want them, they work
380 exactly the same as with L<C<sub>|perlsub/Subroutine-Attributes>.
381
382 =head3 Prototype
383
384 As with L<C<sub>|perlsub/Prototypes>, a prototype, if present, contains hints as to how
385 the compiler should parse calls to this function. This means prototypes have no
386 effect if the function call is compiled before the function declaration has
387 been seen by the compiler or if the function to call is only determined at
388 runtime (e.g. because it's called as a method or through a reference).
389
390 With L<C<sub>|perlsub>, a prototype comes directly after the function name (if
391 any). C<Function::Parameters> reserves this spot for the
392 L<parameter list|/"Parameter list">. To specify a prototype, put it as the
393 first attribute (e.g. C<fun foo :(&$$)>). This is syntactically unambiguous
394 because normal L<attributes|/Attributes> need a name after the colon.
395
396 =head3 Parameter list
397
398 The parameter list is a list of variables enclosed in parentheses, except it's
399 actually a bit more complicated than that. A parameter list can include the
400 following 6 parts, all of which are optional:
401
402 =over
403
404 =item 1. Invocant
405
406 This is a scalar variable followed by a colon (C<:>) and no comma. If an
407 invocant is present in the parameter list, the first element of
408 L<C<@_>|perlvar/@ARG> is automatically L<C<shift>ed|perlfunc/shift> off and
409 placed in this variable. This is intended for methods:
410
411   method new($class: %init) {
412     return bless { %init }, $class;
413   }
414
415   method throw($self:) {
416     die $self;
417   }
418
419 =item 2. Required positional parameters
420
421 The most common kind of parameter. This is simply a comma-separated list of
422 scalars, which are filled from left to right with the arguments that the caller
423 passed in:
424
425   fun add($x, $y) {
426     return $x + $y;
427   }
428   
429   say add(2, 3);  # "5"
430
431 =item 3. Optional positional parameters
432
433 Parameters can be marked as optional by putting an equals sign (C<=>) and an
434 expression (the "default argument") after them. If no corresponding argument is
435 passed in by the caller, the default argument will be used to initialize the
436 parameter:
437
438   fun scale($base, $factor = 2) {
439     return $base * $factor;
440   }
441  
442   say scale(3, 5);  # "15"
443   say scale(3);     # "6"
444
445 The default argument is I<not> cached. Every time a function is called with
446 some optional arguments missing, the corresponding default arguments are
447 evaluated from left to right. This makes no difference for a value like C<2>
448 but it is important for expressions with side effects, such as reference
449 constructors (C<[]>, C<{}>) or function calls.
450
451 Default arguments see not only the surrounding lexical scope of their function
452 but also any preceding parameters. This allows the creation of dynamic defaults
453 based on previous arguments:
454
455   method set_name($self: $nick = $self->default_nick, $real_name = $nick) {
456     $self->{nick} = $nick;
457     $self->{real_name} = $real_name;
458   }
459  
460   $obj->set_name("simplicio");  # same as: $obj->set_name("simplicio", "simplicio");
461
462 Because default arguments are actually evaluated as part of the function body,
463 you can also do silly things like this:
464
465   fun foo($n = return "nope") {
466     "you gave me $n"
467   }
468  
469   say foo(2 + 2);  # "you gave me 4"
470   say foo();       # "nope"
471
472 =item 4. Required named parameters
473
474 By putting a colon (C<:>) in front of a parameter you can make it named
475 instead of positional:
476
477   fun rectangle(:$width, :$height) {
478     ...
479   }
480  
481   rectangle(width => 2, height => 5);
482   rectangle(height => 5, width => 2);  # same thing!
483
484 That is, the caller must specify a key name in addition to the value, but in
485 exchange the order of the arguments doesn't matter anymore. As with hash
486 initialization, you can specify the same key multiple times and the last
487 occurrence wins:
488
489   rectangle(height => 1, width => 2, height => 2, height => 5;
490   # same as: rectangle(width => 2, height => 5);
491
492 You can combine positional and named parameters as long as the positional
493 parameters come first:
494
495   fun named_rectangle($name, :$width, :$height) {
496     ...
497   }
498  
499   named_rectangle("Avocado", width => 0.5, height => 1.2);
500
501 =item 5. Optional named parameters
502
503 As with positional parameters, you can make named parameters optional by
504 specifying a default argument after an equals sign (C<=>):
505
506   fun rectangle(:$width, :$height, :$color = "chartreuse") {
507     ...
508   }
509  
510   rectangle(height => 10, width => 5);
511   # same as: rectangle(height => 10, width => 5, color => "chartreuse");
512
513 =cut
514
515 =pod
516   
517   fun get($url, :$cookie_jar = HTTP::Cookies->new(), :$referrer = $url) {
518     ...
519   }
520
521   my $data = get "http://www.example.com/", referrer => undef;  # overrides $referrer = $url
522
523 The above example shows that passing any value (even C<undef>) will override
524 the default argument.
525
526 =item 6. Slurpy parameter
527
528 Finally you can put an array or hash in the parameter list, which will gobble
529 up the remaining arguments (if any):
530
531   fun foo($x, $y, @rest) { ... }
532  
533   foo "a", "b";            # $x = "a", $y = "b", @rest = ()
534   foo "a", "b", "c";       # $x = "a", $y = "b", @rest = ("c")
535   foo "a", "b", "c", "d";  # $x = "a", $y = "b", @rest = ("c", "d")
536
537 If you combine this with named parameters, the slurpy parameter will end up
538 containing all unrecognized keys:
539
540   fun bar(:$size, @whatev) { ... }
541  
542   bar weight => 20, size => 2, location => [0, -3];
543   # $size = 2, @whatev = ('weight', 20, 'location', [0, -3])
544
545 =back
546
547 Apart from the L<C<shift>|perlfunc/shift> performed by the L<invocant|/"1.
548 Invocant">, all of the above leave L<C<@_>|perlvar/@ARG> unchanged; and if you
549 don't specify a parameter list at all, L<C<@_>|perlvar/@ARG> is all you get.
550
551 =head3 Keyword
552
553 The keywords provided by C<Function::Parameters> are customizable. Since
554 C<Function::Parameters> is actually a L<pragma|perlpragma>, the provided
555 keywords have lexical scope. The following import variants can be used:
556
557 =over
558
559 =item C<use Function::Parameters ':strict'>
560
561 Provides the keywords C<fun> and C<method> (described below) and enables
562 argument checks so that calling a function and omitting a required argument (or
563 passing too many arguments) will throw an error.
564
565 =item C<use Function::Parameters>
566
567 Provides the keywords C<fun> and C<method> (described below) and enables
568 "lax" mode: Omitting a required argument sets it to C<undef> while excess
569 arguments are silently ignored.
570
571 =item C<< use Function::Parameters { KEYWORD1 => TYPE1, KEYWORD2 => TYPE2, ... } >>
572
573 Provides completely custom keywords as described by their types. A "type" is
574 either a string (one of the predefined types C<function>, C<method>,
575 C<classmethod>, C<function_strict>, C<method_strict>, C<classmethod_strict>) or
576 a reference to a hash with the following keys:
577
578 =over
579
580 =item C<name>
581
582 Valid values: C<optional> (default), C<required> (all functions defined with
583 this keyword must have a name), and C<prohibited> (functions defined with this
584 keyword must be anonymous).
585
586 =item C<shift>
587
588 Valid values: strings that look like scalar variables. This lets you specify a
589 default L<invocant|/"1. Invocant">, i.e. a function defined with this keyword
590 that doesn't have an explicit invocant in its parameter list will automatically
591 L<C<shift>|perlfunc/shift> its first argument into the variable specified here.
592
593 =item C<invocant>
594
595 Valid values: booleans. If you set this to a true value, the keyword will
596 accept L<invocants|/"1. Invocant"> in parameter lists; otherwise specifying
597 an invocant in a function defined with this keyword is a syntax error.
598
599 =item C<attributes>
600
601 Valid values: strings containing (source code for) attributes. This causes any
602 function defined with this keyword to have the specified
603 L<attributes|attributes> (in addition to any attributes specified in the
604 function definition itself).
605
606 =item C<default_arguments>
607
608 Valid values: booleans. This property is on by default; use
609 C<< default_arguments => 0 >> to turn it off. This controls whether optional
610 parameters are allowed. If it is turned off, using C<=> in parameter lists is
611 a syntax error.
612
613 =item C<check_argument_count>
614
615 Valid values: booleans. If turned on, functions defined with this keyword will
616 automatically check that they have been passed all required arguments and no
617 excess arguments. If this check fails, an exception will by thrown via
618 L<C<Carp::croak>|Carp>.
619
620 =back
621
622 The predefined type C<function> is equivalent to:
623
624  {
625    name                 => 'optional',
626    invocant             => 0,
627    default_arguments    => 1,
628    check_argument_count => 0,
629  }
630
631 These are all default values, so C<function> is also equivalent to C<{}>.
632
633 C<method> is equivalent to:
634
635  {
636    name                 => 'optional',
637    shift                => '$self',
638    invocant             => 1,
639    attributes           => ':method',
640    default_arguments    => 1,
641    check_argument_count => 0,
642  }
643
644
645 C<classmethod> is equivalent to:
646
647  {
648    name                 => 'optional',
649    shift                => '$class',
650    invocant             => 1,
651    attributes           => ':method',
652    default_arguments    => 1,
653    check_argument_count => 0,
654  }
655
656 C<function_strict>, C<method_strict>, and
657 C<classmethod_strict> are like C<function>, C<method>, and
658 C<classmethod>, respectively, but with C<< check_argument_count => 1 >>.
659
660 =back
661
662 Plain C<use Function::Parameters> is equivalent to
663 C<< use Function::Parameters { fun => 'function', method => 'method' } >>.
664
665 C<use Function::Parameters qw(:strict)> is equivalent to
666 C<< use Function::Parameters { fun => 'function_strict', method => 'method_strict' } >>.
667
668 =head2 Introspection
669
670 You can ask a function at runtime what parameters it has. This functionality is
671 available through the function C<Function::Parameters::info> (which is not
672 exported, so you have to call it by its full name). It takes a reference to a
673 function, and returns either C<undef> (if it knows nothing about the function)
674 or a L<Function::Parameters::Info> object describing the parameter list.
675
676 Note: This feature is implemented using L<Moo>, so you'll need to have L<Moo>
677 installed if you want to call C<Function::Parameters::info> (alternatively, if
678 L<Moose> is already loaded by the time C<Function::Parameters::info> is first
679 called, it will use that instead).
680
681 See L<Function::Parameters::Info> for examples.
682
683 =head2 Wrapping C<Function::Parameters>
684
685 If you want to write a wrapper around C<Function::Parameters>, you only have to
686 call its C<import> method. Due to its L<pragma|perlpragma> nature it always
687 affects the file that is currently being compiled.
688
689  package Some::Wrapper;
690  use Function::Parameters ();
691  sub import {
692    Function::Parameters->import;
693    # or Function::Parameters->import(@custom_import_args);
694  }
695
696 =head2 Experimental feature: Types
697
698 An experimental feature is now available: You can annotate parameters with
699 L<Moose types|Moose::Manual::Types>. That is, before each parameter you can put
700 a type specification consisting of identifiers (C<Foo>), unions (C<... | ...>),
701 and parametric types (C<...[...]>). Example:
702
703   fun foo(Int $n, ArrayRef[String | CodeRef] $cb) { ... }
704
705 If you do this, L<Moose> will be loaded automatically (if that hasn't happened
706 yet). These specifications are parsed and validated using
707 L<C<Moose::Util::TypeConstraints::find_or_parse_type_constraint>|Moose::Util::TypeConstraints/find_or_parse_type_constraint>.
708
709 If you are in "lax" mode, nothing further happens and the types are ignored. If
710 you are in "strict" mode, C<Function::Parameters> generates code to make sure
711 any values passed in conform to the type (via
712 L<< C<< $constraint->check($value) >>|Moose::Meta::TypeConstraint/$constraint->check($value) >>).
713
714 In addition, these type constraints are inspectable through the
715 L<Function::Parameters::Info> object returned by
716 L<C<Function::Parameters::info>|/Introspection>.
717
718 =head2 Experimental experimental feature: Type expressions
719
720 An even more experimental feature is the ability to specify arbitrary
721 expressions as types. The syntax for this is like the literal types described
722 above, but with an expression wrapped in parentheses (C<( EXPR )>). Example:
723
724   fun foo(('Int') $n, ($othertype) $x) { ... }
725
726 Every type expression must return either a string (which is resolved as for
727 literal types), or a L<type constraint object|Moose::Meta::TypeConstraint>
728 (providing C<check> and C<get_message> methods).
729
730 Note that these expressions are evaluated (once) at parse time (similar to
731 C<BEGIN> blocks), so make sure that any variables you use are set and any
732 functions you call are defined at parse time.
733
734 =head2 How it works
735
736 The module is actually written in L<C|perlxs> and uses
737 L<C<PL_keyword_plugin>|perlapi/PL_keyword_plugin> to generate opcodes directly.
738 However, you can run L<C<perl -MO=Deparse ...>|B::Deparse> on your code to see
739 what happens under the hood. In the simplest case (no argument checks, possibly
740 an L<invocant|/"1. Invocant">, required positional/slurpy parameters only), the
741 generated code corresponds to:
742
743   fun foo($x, $y, @z) { ... }
744   # ... turns into ...
745   sub foo { my ($x, $y, @z) = @_; sub foo; ... }
746
747   method bar($x, $y, @z) { ... }
748   # ... turns into ...
749   sub bar :method { my $self = shift; my ($x, $y, @z) = @_; sub bar; ... }
750
751 =head1 SUPPORT AND DOCUMENTATION
752
753 After installing, you can find documentation for this module with the
754 perldoc command.
755
756     perldoc Function::Parameters
757
758 You can also look for information at:
759
760 =over
761
762 =item MetaCPAN
763
764 L<https://metacpan.org/module/Function%3A%3AParameters>
765
766 =item RT, CPAN's request tracker
767
768 L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Function-Parameters>
769
770 =item AnnoCPAN, Annotated CPAN documentation
771
772 L<http://annocpan.org/dist/Function-Parameters>
773
774 =item CPAN Ratings
775
776 L<http://cpanratings.perl.org/d/Function-Parameters>
777
778 =item Search CPAN
779
780 L<http://search.cpan.org/dist/Function-Parameters/>
781
782 =back
783
784 =head1 SEE ALSO
785
786 L<Function::Parameters::Info>
787
788 =head1 AUTHOR
789
790 Lukas Mai, C<< <l.mai at web.de> >>
791
792 =head1 COPYRIGHT & LICENSE
793
794 Copyright 2010-2013 Lukas Mai.
795
796 This program is free software; you can redistribute it and/or modify it
797 under the terms of either: the GNU General Public License as published
798 by the Free Software Foundation; or the Artistic License.
799
800 See http://dev.perl.org/licenses/ for more information.
801
802 =cut