3c154102b3535d463eea48896ebc61d623ddf213
[p5sagit/Function-Parameters.git] / lib / Function / Parameters.pm
1 package Function::Parameters;
2
3 use v5.14.0;
4
5 use strict;
6 use warnings;
7
8 use Carp qw(confess);
9
10 use XSLoader;
11 BEGIN {
12         our $VERSION = '0.09';
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 =~ /^\s*:\s*[^\W\d]\w*\s*(?:(?:\s|:\s*)[^\W\d]\w*\s*)*(?:\(|\z)/
26                 or confess qq{"$attrs" doesn't look like valid attributes};
27 }
28
29 my @bare_arms = qw(function method);
30 my %type_map = (
31         function => {
32                 name => 'optional',
33                 default_arguments => 1,
34                 check_argument_count => 0,
35         },
36         method   => {
37                 name => 'optional',
38                 default_arguments => 1,
39                 check_argument_count => 0,
40                 attrs => ':method',
41                 shift => '$self',
42                 invocant => 1,
43         },
44         classmethod   => {
45                 name => 'optional',
46                 default_arguments => 1,
47                 check_argument_count => 0,
48                 attributes => ':method',
49                 shift => '$class',
50                 invocant => 1,
51         },
52 );
53 for my $k (keys %type_map) {
54         $type_map{$k . '_strict'} = {
55                 %{$type_map{$k}},
56                 check_argument_count => 1,
57         };
58 }
59
60 sub import {
61         my $class = shift;
62
63         if (!@_) {
64                 @_ = {
65                         fun => 'function',
66                         method => 'method',
67                 };
68         }
69         if (@_ == 1 && $_[0] eq ':strict') {
70                 @_ = {
71                         fun => 'function_strict',
72                         method => 'method_strict',
73                 };
74         }
75         if (@_ == 1 && ref($_[0]) eq 'HASH') {
76                 @_ = map [$_, $_[0]{$_}], keys %{$_[0]};
77         }
78
79         my %spec;
80
81         my $bare = 0;
82         for my $proto (@_) {
83                 my $item = ref $proto
84                         ? $proto
85                         : [$proto, $bare_arms[$bare++] || confess(qq{Don't know what to do with "$proto"})]
86                 ;
87                 my ($name, $proto_type) = @$item;
88                 _assert_valid_identifier $name;
89
90                 unless (ref $proto_type) {
91                         # use '||' instead of 'or' to preserve $proto_type in the error message
92                         $proto_type = $type_map{$proto_type}
93                                 || confess qq["$proto_type" doesn't look like a valid type (one of ${\join ', ', sort keys %type_map})];
94                 }
95
96                 my %type = %$proto_type;
97                 my %clean;
98
99                 $clean{name} = delete $type{name} || 'optional';
100                 $clean{name} =~ /^(?:optional|required|prohibited)\z/
101                         or confess qq["$clean{name}" doesn't look like a valid name attribute (one of optional, required, prohibited)];
102
103                 $clean{shift} = delete $type{shift} || '';
104                 _assert_valid_identifier $clean{shift}, 1 if $clean{shift};
105
106                 $clean{attrs} = join ' ', map delete $type{$_} || (), qw(attributes attrs);
107                 _assert_valid_attributes $clean{attrs} if $clean{attrs};
108                 
109                 $clean{default_arguments} =
110                         exists $type{default_arguments}
111                         ? !!delete $type{default_arguments}
112                         : 1
113                 ;
114                 $clean{check_argument_count} = !!delete $type{check_argument_count};
115                 $clean{invocant} = !!delete $type{invocant};
116
117                 %type and confess "Invalid keyword property: @{[keys %type]}";
118
119                 $spec{$name} = \%clean;
120         }
121         
122         for my $kw (keys %spec) {
123                 my $type = $spec{$kw};
124
125                 my $flags =
126                         $type->{name} eq 'prohibited' ? FLAG_ANON_OK :
127                         $type->{name} eq 'required' ? FLAG_NAME_OK :
128                         FLAG_ANON_OK | FLAG_NAME_OK
129                 ;
130                 $flags |= FLAG_DEFAULT_ARGS if $type->{default_arguments};
131                 $flags |= FLAG_CHECK_NARGS if $type->{check_argument_count};
132                 $flags |= FLAG_INVOCANT if $type->{invocant};
133                 $^H{HINTK_FLAGS_ . $kw} = $flags;
134                 $^H{HINTK_SHIFT_ . $kw} = $type->{shift};
135                 $^H{HINTK_ATTRS_ . $kw} = $type->{attrs};
136                 $^H{+HINTK_KEYWORDS} .= "$kw ";
137         }
138 }
139
140 sub unimport {
141         my $class = shift;
142
143         if (!@_) {
144                 delete $^H{+HINTK_KEYWORDS};
145                 return;
146         }
147
148         for my $kw (@_) {
149                 $^H{+HINTK_KEYWORDS} =~ s/(?<![^ ])\Q$kw\E //g;
150         }
151 }
152
153
154 'ok'
155
156 __END__
157
158 =encoding UTF-8
159
160 =head1 NAME
161
162 Function::Parameters - subroutine definitions with parameter lists
163
164 =head1 SYNOPSIS
165
166  use Function::Parameters;
167  
168  # simple function
169  fun foo($bar, $baz) {
170    return $bar + $baz;
171  }
172  
173  # function with prototype
174  fun mymap($fun, @args)
175    :(&@)
176  {
177    my @res;
178    for (@args) {
179      push @res, $fun->($_);
180    }
181    @res
182  }
183  
184  print "$_\n" for mymap { $_ * 2 } 1 .. 4;
185  
186  # method with implicit $self
187  method set_name($name) {
188    $self->{name} = $name;
189  }
190  
191  # method with explicit invocant
192  method new($class: %init) {
193    return bless { %init }, $class;
194  }
195  
196  # function with default arguments
197  fun search($haystack, $needle = qr/^(?!)/, $offset = 0) {
198    ...
199  }
200  
201  # method with default arguments
202  method skip($amount = 1) {
203    $self->{position} += $amount;
204  }
205
206 =cut
207
208 =pod
209
210  # use different keywords
211  use Function::Parameters {
212    proc => 'function',
213    meth => 'method',
214  };
215  
216  my $f = proc ($x) { $x * 2 };
217  meth get_age() {
218    return $self->{age};
219  }
220
221 =head1 DESCRIPTION
222
223 This module lets you use parameter lists in your subroutines. Thanks to
224 L<PL_keyword_plugin|perlapi/PL_keyword_plugin> it works without source filters.
225
226 WARNING: This is my first attempt at writing L<XS code|perlxs> and I have
227 almost no experience with perl's internals. So while this module might
228 appear to work, it could also conceivably make your programs segfault.
229 Consider this module alpha quality.
230
231 =head2 Basic stuff
232
233 To use this new functionality, you have to use C<fun> instead of C<sub> -
234 C<sub> continues to work as before. The syntax is almost the same as for
235 C<sub>, but after the subroutine name (or directly after C<fun> if you're
236 writing an anonymous sub) you can write a parameter list in parentheses. This
237 list consists of comma-separated variables.
238
239 The effect of C<fun foo($bar, $baz) {> is as if you'd written
240 C<sub foo { my ($bar, $baz) = @_; >, i.e. the parameter list is simply
241 copied into L<my|perlfunc/my-EXPR> and initialized from L<@_|perlvar/"@_">.
242
243 In addition you can use C<method>, which understands the same syntax as C<fun>
244 but automatically creates a C<$self> variable for you. So by writing
245 C<method foo($bar, $baz) {> you get the same effect as
246 C<sub foo { my $self = shift; my ($bar, $baz) = @_; >.
247
248 =head2 Customizing the generated keywords
249
250 You can customize the names of the keywords injected into your scope. To do
251 that you pass a reference to a hash mapping keywords to types in the import
252 list:
253
254  use Function::Parameters {
255    KEYWORD1 => TYPE1,
256    KEYWORD2 => TYPE2,
257    ...
258  };
259
260 Or more concretely:
261
262  use Function::Parameters { proc => 'function', meth => 'method' }; # -or-
263  use Function::Parameters { proc => 'function' }; # -or-
264  use Function::Parameters { meth => 'method' }; # etc.
265
266 The first line creates two keywords, C<proc> and C<meth> (for defining
267 functions and methods, respectively). The last two lines only create one
268 keyword. Generally the hash keys (keywords) can be any identifiers you want
269 while the values (types) have to be either a hash reference (see below) or
270 C<'function'>, C<'method'>, C<'classmethod'>, C<'function_strict'>,
271 C<'method_strict'>, or C<'classmethod_strict'>. The main difference between
272 C<'function'> and C<'method'> is that C<'method'>s automatically
273 L<shift|perlfunc/shift> their first argument into C<$self> (C<'classmethod'>s
274 are similar but shift into C<$class>).
275
276 The following shortcuts are available:
277
278  use Function::Parameters;
279     # is equivalent to #
280  use Function::Parameters { fun => 'function', method => 'method' };
281
282 =cut
283
284 =pod
285
286  use Function::Parameters ':strict';
287     # is equivalent to #
288  use Function::Parameters { fun => 'function_strict', method => 'method_strict' };
289
290 =pod
291
292 The following shortcuts are deprecated and may be removed from a future version
293 of this module:
294
295  # DEPRECATED
296  use Function::Parameters 'foo';
297    # is equivalent to #
298  use Function::Parameters { 'foo' => 'function' };
299
300 =cut
301
302 =pod
303
304  # DEPRECATED
305  use Function::Parameters 'foo', 'bar';
306    # is equivalent to #
307  use Function::Parameters { 'foo' => 'function', 'bar' => 'method' };
308
309 That is, if you want to create custom keywords with L<Function::Parameters>,
310 use a hashref, not a list of strings.
311
312 You can tune the properties of the generated keywords even more by passing
313 a hashref instead of a string. This hash can have the following keys:
314
315 =over
316
317 =item C<name>
318
319 Valid values: C<optional> (default), C<required> (all uses of this keyword must
320 specify a function name), and C<prohibited> (all uses of this keyword must not
321 specify a function name). This means a C<< name => 'prohibited' >> keyword can
322 only be used for defining anonymous functions.
323
324 =item C<shift>
325
326 Valid values: strings that look like a scalar variable. Any function created by
327 this keyword will automatically L<shift|perlfunc/shift> its first argument into
328 a local variable whose name is specified here.
329
330 =item C<invocant>
331
332 Valid values: booleans. This lets users of this keyword specify an explicit
333 invocant, that is, the first parameter may be followed by a C<:> (colon)
334 instead of a comma and will by initialized by shifting the first element off
335 C<@_>.
336
337 You can combine C<shift> and C<invocant>, in which case the variable named in
338 C<shift> serves as a default shift target for functions that don't use an
339 explicit invocant.
340
341 =item C<attributes>, C<attrs>
342
343 Valid values: strings that are valid source code for attributes. Any value
344 specified here will be inserted as a subroutine attribute in the generated
345 code. Thus:
346
347  use Function::Parameters { sub_l => { attributes => ':lvalue' } };
348  sub_l foo() {
349    ...
350  }
351
352 turns into
353
354  sub foo :lvalue {
355    ...
356  }
357
358 It is recommended that you use C<attributes> in new code but C<attrs> is also
359 accepted for now.
360
361 =item C<default_arguments>
362
363 Valid values: booleans. This property is on by default, so you have to pass
364 C<< default_arguments => 0 >> to turn it off. If it is disabled, using C<=> in
365 a parameter list causes a syntax error. Otherwise it lets you specify
366 default arguments directly in the parameter list:
367
368  fun foo($x, $y = 42, $z = []) {
369    ...
370  }
371
372 turns into
373
374  sub foo {
375    my ($x, $y, $z) = @_;
376    $y = 42 if @_ < 2;
377    $z = [] if @_ < 3;
378    ...
379  }
380
381 You can even refer to previous parameters in the same parameter list:
382
383  print fun ($x, $y = $x + 1) { "$x and $y" }->(9);  # "9 and 10"
384
385 This also works with the implicit first parameter of methods:
386
387  method scale($factor = $self->default_factor) {
388    $self->{amount} *= $factor;
389  }
390
391 =item C<check_argument_count>
392
393 Valid values: booleans. This property is off by default. If it is enabled, the
394 generated code will include checks to make sure the number of passed arguments
395 is correct (and otherwise throw an exception via L<Carp::croak|Carp>):
396
397   fun foo($x, $y = 42, $z = []) {
398     ...
399   }
400
401 turns into
402
403  sub foo {
404    Carp::croak "Not enough arguments for fun foo" if @_ < 1;
405    Carp::croak "Too many arguments for fun foo" if @_ > 3;
406    my ($x, $y, $z) = @_;
407    $y = 42 if @_ < 2;
408    $z = [] if @_ < 3;
409    ...
410  }
411
412 =back
413
414 Plain C<'function'> is equivalent to:
415
416  {
417    name => 'optional',
418    default_arguments => 1,
419    check_argument_count => 0,
420  }
421
422 (These are all default values so C<'function'> is also equivalent to C<{}>.)
423
424 C<'function_strict'> is like C<'function'> but with
425 C<< check_argument_count => 1 >>.
426
427 C<'method'> is equivalent to:
428
429  {
430    name => 'optional',
431    default_arguments => 1,
432    check_argument_count => 0,
433    attributes => ':method',
434    shift => '$self',
435    invocant => 1,
436  }
437
438 C<'method_strict'> is like C<'method'> but with
439 C<< check_argument_count => 1 >>.
440
441 C<'classmethod'> is equivalent to:
442
443  {
444    name => 'optional',
445    default_arguments => 1,
446    check_argument_count => 0,
447    attributes => ':method',
448    shift => '$class',
449    invocant => 1,
450  }
451
452 C<'classmethod_strict'> is like C<'classmethod'> but with
453 C<< check_argument_count => 1 >>.
454
455 =head2 Syntax and generated code
456
457 Normally, Perl subroutines are not in scope in their own body, meaning the
458 parser doesn't know the name C<foo> or its prototype while processing the body
459 of C<sub foo ($) { foo $bar[1], $bar[0]; }>, parsing it as
460 C<$bar-E<gt>foo([1], $bar[0])>. Yes. You can add parens to change the
461 interpretation of this code, but C<foo($bar[1], $bar[0])> will only trigger
462 a I<foo() called too early to check prototype> warning. This module attempts
463 to fix all of this by adding a subroutine declaration before the function body,
464 so the parser knows the name (and possibly prototype) while it processes the
465 body. Thus C<fun foo($x) :($) { $x }> really turns into
466 C<sub foo ($) { sub foo ($); my ($x) = @_; $x }>.
467
468 If you need L<subroutine attributes|perlsub/Subroutine-Attributes>, you can
469 put them after the parameter list with their usual syntax.
470
471 Syntactically, these new parameter lists live in the spot normally occupied
472 by L<prototypes|perlsub/"Prototypes">. However, you can include a prototype by
473 specifying it as the first attribute (this is syntactically unambiguous
474 because normal attributes have to start with a letter while a prototype starts
475 with C<(>).
476
477 As an example, the following declaration uses every available feature
478 (subroutine name, parameter list, default arguments, prototype, default
479 attributes, attributes, argument count checks, and implicit C<$self> overriden
480 by an explicit invocant declaration):
481
482  method foo($this: $x, $y, $z = sqrt 5)
483    :($$$;$)
484    :lvalue
485    :Banana(2 + 2)
486  {
487    ...
488  }
489
490 And here's what it turns into:
491
492  sub foo ($$$;$) :method :lvalue :Banana(2 + 2) {
493    sub foo ($$$;$);
494    Carp::croak "Not enough arguments for method foo" if @_ < 3;
495    Carp::croak "Too many arguments for method foo" if @_ > 4;
496    my $this = shift;
497    my ($x, $y, $z) = @_;
498    $z = sqrt 5 if @_ < 3;
499    ...
500  }
501
502 Another example:
503
504  my $coderef = fun ($p, $q)
505    :(;$$)
506    :lvalue
507    :Gazebo((>:O)) {
508    ...
509  };
510
511 And the generated code:
512
513  my $coderef = sub (;$$) :lvalue :Gazebo((>:O)) {
514    # vvv   only if check_argument_count is enabled    vvv
515    Carp::croak "Not enough arguments for fun (anon)" if @_ < 2;
516    Carp::croak "Too many arguments for fun (anon)" if @_ > 2;
517    # ^^^                                              ^^^
518    my ($p, $q) = @_;
519    ...
520  };
521
522 =head2 Wrapping Function::Parameters
523
524 If you want to wrap L<Function::Parameters>, you just have to call its
525 C<import> method. It always applies to the file that is currently being parsed
526 and its effects are L<lexical|perlpragma> (i.e. it works like L<warnings> or
527 L<strict>).
528
529  package Some::Wrapper;
530  use Function::Parameters ();
531  sub import {
532    Function::Parameters->import;
533    # or Function::Parameters->import(@custom_import_args);
534  }
535
536 =head1 AUTHOR
537
538 Lukas Mai, C<< <l.mai at web.de> >>
539
540 =head1 COPYRIGHT & LICENSE
541
542 Copyright 2010, 2011, 2012 Lukas Mai.
543
544 This program is free software; you can redistribute it and/or modify it
545 under the terms of either: the GNU General Public License as published
546 by the Free Software Foundation; or the Artistic License.
547
548 See http://dev.perl.org/licenses/ for more information.
549
550 =cut