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