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