update Changes
[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 {
d45c9037 12 our $VERSION = '0.06_01';
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
7a63380c 163 fun mymap($fun, @args) :(&@) {
164 my @res;
165 for (@args) {
166 push @res, $fun->($_);
167 }
168 @res
169 }
170
171 print "$_\n" for mymap { $_ * 2 } 1 .. 4;
125c067e 172
698e861c 173 # method with implicit $self
125c067e 174 method set_name($name) {
175 $self->{name} = $name;
176 }
7a63380c 177
698e861c 178 # function with default arguments
179 fun search($haystack, $needle = qr/^(?!)/, $offset = 0) {
180 ...
181 }
182
183 # method with default arguments
184 method skip($amount = 1) {
185 $self->{position} += $amount;
186 }
187
125c067e 188=cut
189
190=pod
191
698e861c 192 # use different keywords
63a24d7c 193 use Function::Parameters {
194 proc => 'function',
195 meth => 'method',
196 };
c9a39f6b 197
125c067e 198 my $f = proc ($x) { $x * 2 };
199 meth get_age() {
200 return $self->{age};
201 }
202
7a63380c 203=head1 DESCRIPTION
204
205This module lets you use parameter lists in your subroutines. Thanks to
63a24d7c 206L<PL_keyword_plugin|perlapi/PL_keyword_plugin> it works without source filters.
7a63380c 207
db81d362 208WARNING: This is my first attempt at writing L<XS code|perlxs> and I have
7a63380c 209almost no experience with perl's internals. So while this module might
210appear to work, it could also conceivably make your programs segfault.
211Consider this module alpha quality.
212
213=head2 Basic stuff
214
215To use this new functionality, you have to use C<fun> instead of C<sub> -
216C<sub> continues to work as before. The syntax is almost the same as for
217C<sub>, but after the subroutine name (or directly after C<fun> if you're
125c067e 218writing an anonymous sub) you can write a parameter list in parentheses. This
7a63380c 219list consists of comma-separated variables.
220
221The effect of C<fun foo($bar, $baz) {> is as if you'd written
222C<sub foo { my ($bar, $baz) = @_; >, i.e. the parameter list is simply
95915793 223copied into L<my|perlfunc/my-EXPR> and initialized from L<@_|perlvar/"@_">.
7a63380c 224
125c067e 225In addition you can use C<method>, which understands the same syntax as C<fun>
226but automatically creates a C<$self> variable for you. So by writing
227C<method foo($bar, $baz) {> you get the same effect as
228C<sub foo { my $self = shift; my ($bar, $baz) = @_; >.
7a63380c 229
125c067e 230=head2 Customizing the generated keywords
c9a39f6b 231
63a24d7c 232You can customize the names of the keywords injected into your scope. To do
698e861c 233that you pass a reference to a hash mapping keywords to types in the import
234list:
235
236 use Function::Parameters {
237 KEYWORD1 => TYPE1,
238 KEYWORD2 => TYPE2,
239 ...
240 };
241
242Or more concretely:
7a63380c 243
125c067e 244 use Function::Parameters { proc => 'function', meth => 'method' }; # -or-
245 use Function::Parameters { proc => 'function' }; # -or-
a23979e1 246 use Function::Parameters { meth => 'method' }; # etc.
125c067e 247
248The first line creates two keywords, C<proc> and C<meth> (for defining
249functions and methods, respectively). The last two lines only create one
698e861c 250keyword. Generally the hash keys (keywords) can be any identifiers you want
7817d698 251while the values (types) have to be either a hash reference (see below) or
252C<'function'>, C<'method'>, C<'classmethod'>, C<'function_strict'>,
253C<'method_strict'>, or C<'classmethod_strict'>. The main difference between
698e861c 254C<'function'> and C<'method'> is that C<'method'>s automatically
255L<shift|perlfunc/shift> their first argument into C<$self> (C<'classmethod'>s
256are similar but shift into C<$class>).
125c067e 257
258The following shortcuts are available:
259
260 use Function::Parameters;
261 # is equivalent to #
262 use Function::Parameters { fun => 'function', method => 'method' };
263
264=cut
265
266=pod
267
63a24d7c 268The following shortcuts are deprecated and may be removed from a future version
698e861c 269of this module:
63a24d7c 270
271 # DEPRECATED
125c067e 272 use Function::Parameters 'foo';
273 # is equivalent to #
274 use Function::Parameters { 'foo' => 'function' };
275
276=cut
277
278=pod
279
63a24d7c 280 # DEPRECATED
125c067e 281 use Function::Parameters 'foo', 'bar';
282 # is equivalent to #
283 use Function::Parameters { 'foo' => 'function', 'bar' => 'method' };
284
63a24d7c 285That is, if you want to pass arguments to L<Function::Parameters>, use a
286hashref, not a list of strings.
287
698e861c 288You can customize the properties of the generated keywords even more by passing
289a hashref instead of a string. This hash can have the following keys:
ce052c57 290
291=over
292
293=item C<name>
294
295Valid values: C<optional> (default), C<required> (all uses of this keyword must
296specify a function name), and C<prohibited> (all uses of this keyword must not
297specify a function name). This means a C<< name => 'prohibited' >> keyword can
298only be used for defining anonymous functions.
299
300=item C<shift>
301
302Valid values: strings that look like a scalar variable. Any function created by
303this keyword will automatically L<shift|perlfunc/shift> its first argument into
63a24d7c 304a local variable whose name is specified here.
ce052c57 305
698e861c 306=item C<attributes>, C<attrs>
273c6544 307
308Valid values: strings that are valid source code for attributes. Any value
309specified here will be inserted as a subroutine attribute in the generated
310code. Thus:
311
698e861c 312 use Function::Parameters { sub_l => { attributes => ':lvalue' } };
273c6544 313 sub_l foo() {
314 ...
315 }
316
317turns into
318
319 sub foo :lvalue {
320 ...
321 }
322
698e861c 323It is recommended that you use C<attributes> in new code but C<attrs> is also
324accepted for now.
325
326=item C<default_arguments>
327
328Valid values: booleans. This property is on by default, so you have to pass
329C<< default_arguments => 0 >> to turn it off. If it is disabled, using C<=> in
330a parameter list causes a syntax error. Otherwise it lets you specify
331default arguments directly in the parameter list:
332
333 fun foo($x, $y = 42, $z = []) {
334 ...
335 }
336
337turns into
338
339 sub foo {
340 my ($x, $y, $z) = @_;
341 $y = 42 if @_ < 2;
342 $z = [] if @_ < 3;
343 ...
344 }
345
1e0f1595 346You can even refer to previous parameters in the same parameter list:
698e861c 347
1e0f1595 348 print fun ($x, $y = $x + 1) { "$x and $y" }->(9); # "9 and 10"
698e861c 349
1e0f1595 350This also works with the implicit first parameter of methods:
698e861c 351
1e0f1595 352 method scale($factor = $self->default_factor) {
353 $self->{amount} *= $factor;
354 }
698e861c 355
356=item C<check_argument_count>
357
358Valid values: booleans. This property is off by default. If it is enabled, the
359generated code will include checks to make sure the number of passed arguments
360is correct (and otherwise throw an exception via L<Carp::croak|Carp>):
361
362 fun foo($x, $y = 42, $z = []) {
363 ...
364 }
365
366turns into
367
368 sub foo {
369 Carp::croak "Not enough arguments for fun foo" if @_ < 1;
370 Carp::croak "Too many arguments for fun foo" if @_ > 3;
371 my ($x, $y, $z) = @_;
372 $y = 42 if @_ < 2;
373 $z = [] if @_ < 3;
374 ...
375 }
376
ce052c57 377=back
378
698e861c 379Plain C<'function'> is equivalent to:
380
381 {
382 name => 'optional',
383 default_arguments => 1,
384 check_argument_count => 0,
385 }
386
387(These are all default values so C<'function'> is also equivalent to C<{}>.)
388
7817d698 389C<'function_strict'> is like C<'function'> but with
390C<< check_argument_count => 1 >>.
391
698e861c 392C<'method'> is equivalent to:
393
394 {
395 name => 'optional',
396 default_arguments => 1,
397 check_argument_count => 0,
398 attributes => ':method',
399 shift => '$self',
400 }
401
7817d698 402C<'method_strict'> is like C<'method'> but with
403C<< check_argument_count => 1 >>.
404
698e861c 405C<'classmethod'> is equivalent to:
406
407 {
408 name => 'optional',
409 default_arguments => 1,
410 check_argument_count => 0,
411 attributes => ':method',
412 shift => '$class',
413 }
ce052c57 414
7817d698 415C<'classmethod_strict'> is like C<'classmethod'> but with
416C<< check_argument_count => 1 >>.
417
63a24d7c 418=head2 Syntax and generated code
7a63380c 419
420Normally, Perl subroutines are not in scope in their own body, meaning the
63a24d7c 421parser doesn't know the name C<foo> or its prototype while processing the body
422of C<sub foo ($) { foo $bar[1], $bar[0]; }>, parsing it as
7a63380c 423C<$bar-E<gt>foo([1], $bar[0])>. Yes. You can add parens to change the
424interpretation of this code, but C<foo($bar[1], $bar[0])> will only trigger
425a I<foo() called too early to check prototype> warning. This module attempts
698e861c 426to fix all of this by adding a subroutine declaration before the function body,
7a63380c 427so the parser knows the name (and possibly prototype) while it processes the
428body. Thus C<fun foo($x) :($) { $x }> really turns into
698e861c 429C<sub foo ($) { sub foo ($); my ($x) = @_; $x }>.
7a63380c 430
95915793 431If you need L<subroutine attributes|perlsub/Subroutine-Attributes>, you can
125c067e 432put them after the parameter list with their usual syntax.
433
434Syntactically, these new parameter lists live in the spot normally occupied
435by L<prototypes|perlsub/"Prototypes">. However, you can include a prototype by
436specifying it as the first attribute (this is syntactically unambiguous
63a24d7c 437because normal attributes have to start with a letter while a prototype starts
438with C<(>).
439
698e861c 440As an example, the following declaration uses every available feature
441(subroutine name, parameter list, default arguments, prototype, default
442attributes, attributes, argument count checks, and implicit C<$self>):
63a24d7c 443
698e861c 444 method foo($x, $y, $z = sqrt 5) :($$$;$) :lvalue :Banana(2 + 2) {
63a24d7c 445 ...
446 }
447
448And here's what it turns into:
449
698e861c 450 sub foo ($$$;$) :method :lvalue :Banana(2 + 2) {
451 sub foo ($$$;$);
452 Carp::croak "Not enough arguments for method foo" if @_ < 2;
453 Carp::croak "Too many arguments for method foo" if @_ > 4;
454 my $self = shift;
455 my ($x, $y, $z) = @_;
456 $z = sqrt 5 if @_ < 3;
63a24d7c 457 ...
458 }
459
460Another example:
461
462 my $coderef = fun ($p, $q) :(;$$)
463 :lvalue
464 :Gazebo((>:O)) {
465 ...
466 };
467
468And the generated code:
469
698e861c 470 my $coderef = sub (;$$) :lvalue :Gazebo((>:O)) {
471 # vvv only if check_argument_count is enabled vvv
472 Carp::croak "Not enough arguments for fun (anon)" if @_ < 2;
473 Carp::croak "Too many arguments for fun (anon)" if @_ > 2;
7817d698 474 # ^^^ ^^^
698e861c 475 my ($p, $q) = @_;
63a24d7c 476 ...
477 };
478
479=head2 Wrapping Function::Parameters
125c067e 480
db81d362 481If you want to wrap L<Function::Parameters>, you just have to call its
482C<import> method. It always applies to the file that is currently being parsed
95915793 483and its effects are L<lexical|perlpragma> (i.e. it works like L<warnings> or
484L<strict>).
63a24d7c 485
486 package Some::Wrapper;
487 use Function::Parameters ();
488 sub import {
489 Function::Parameters->import;
698e861c 490 # or Function::Parameters->import(@custom_import_args);
63a24d7c 491 }
eeb7df5f 492
7a63380c 493=head1 AUTHOR
494
495Lukas Mai, C<< <l.mai at web.de> >>
496
497=head1 COPYRIGHT & LICENSE
498
db81d362 499Copyright 2010, 2011, 2012 Lukas Mai.
7a63380c 500
501This program is free software; you can redistribute it and/or modify it
502under the terms of either: the GNU General Public License as published
503by the Free Software Foundation; or the Artistic License.
504
505See http://dev.perl.org/licenses/ for more information.
506
507=cut