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