register destructor for the generated optree in case of exceptions
[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 {
1d143321 12 our $VERSION = '0.06';
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
346except that none of the parameters are in scope in the expressions that specify
347default values. Thus:
348
349 my $var = "outer";
350
351 fun foo($var, $wat = $var) {
352 # $wat will default to "outer", not to what was passed
353 # as the first argument!
354 ...
355 }
356
357This may change in a future version of this module.
358
359=item C<check_argument_count>
360
361Valid values: booleans. This property is off by default. If it is enabled, the
362generated code will include checks to make sure the number of passed arguments
363is correct (and otherwise throw an exception via L<Carp::croak|Carp>):
364
365 fun foo($x, $y = 42, $z = []) {
366 ...
367 }
368
369turns into
370
371 sub foo {
372 Carp::croak "Not enough arguments for fun foo" if @_ < 1;
373 Carp::croak "Too many arguments for fun foo" if @_ > 3;
374 my ($x, $y, $z) = @_;
375 $y = 42 if @_ < 2;
376 $z = [] if @_ < 3;
377 ...
378 }
379
ce052c57 380=back
381
698e861c 382Plain C<'function'> is equivalent to:
383
384 {
385 name => 'optional',
386 default_arguments => 1,
387 check_argument_count => 0,
388 }
389
390(These are all default values so C<'function'> is also equivalent to C<{}>.)
391
7817d698 392C<'function_strict'> is like C<'function'> but with
393C<< check_argument_count => 1 >>.
394
698e861c 395C<'method'> is equivalent to:
396
397 {
398 name => 'optional',
399 default_arguments => 1,
400 check_argument_count => 0,
401 attributes => ':method',
402 shift => '$self',
403 }
404
7817d698 405C<'method_strict'> is like C<'method'> but with
406C<< check_argument_count => 1 >>.
407
698e861c 408C<'classmethod'> is equivalent to:
409
410 {
411 name => 'optional',
412 default_arguments => 1,
413 check_argument_count => 0,
414 attributes => ':method',
415 shift => '$class',
416 }
ce052c57 417
7817d698 418C<'classmethod_strict'> is like C<'classmethod'> but with
419C<< check_argument_count => 1 >>.
420
63a24d7c 421=head2 Syntax and generated code
7a63380c 422
423Normally, Perl subroutines are not in scope in their own body, meaning the
63a24d7c 424parser doesn't know the name C<foo> or its prototype while processing the body
425of C<sub foo ($) { foo $bar[1], $bar[0]; }>, parsing it as
7a63380c 426C<$bar-E<gt>foo([1], $bar[0])>. Yes. You can add parens to change the
427interpretation of this code, but C<foo($bar[1], $bar[0])> will only trigger
428a I<foo() called too early to check prototype> warning. This module attempts
698e861c 429to fix all of this by adding a subroutine declaration before the function body,
7a63380c 430so the parser knows the name (and possibly prototype) while it processes the
431body. Thus C<fun foo($x) :($) { $x }> really turns into
698e861c 432C<sub foo ($) { sub foo ($); my ($x) = @_; $x }>.
7a63380c 433
95915793 434If you need L<subroutine attributes|perlsub/Subroutine-Attributes>, you can
125c067e 435put them after the parameter list with their usual syntax.
436
437Syntactically, these new parameter lists live in the spot normally occupied
438by L<prototypes|perlsub/"Prototypes">. However, you can include a prototype by
439specifying it as the first attribute (this is syntactically unambiguous
63a24d7c 440because normal attributes have to start with a letter while a prototype starts
441with C<(>).
442
698e861c 443As an example, the following declaration uses every available feature
444(subroutine name, parameter list, default arguments, prototype, default
445attributes, attributes, argument count checks, and implicit C<$self>):
63a24d7c 446
698e861c 447 method foo($x, $y, $z = sqrt 5) :($$$;$) :lvalue :Banana(2 + 2) {
63a24d7c 448 ...
449 }
450
451And here's what it turns into:
452
698e861c 453 sub foo ($$$;$) :method :lvalue :Banana(2 + 2) {
454 sub foo ($$$;$);
455 Carp::croak "Not enough arguments for method foo" if @_ < 2;
456 Carp::croak "Too many arguments for method foo" if @_ > 4;
457 my $self = shift;
458 my ($x, $y, $z) = @_;
459 $z = sqrt 5 if @_ < 3;
63a24d7c 460 ...
461 }
462
463Another example:
464
465 my $coderef = fun ($p, $q) :(;$$)
466 :lvalue
467 :Gazebo((>:O)) {
468 ...
469 };
470
471And the generated code:
472
698e861c 473 my $coderef = sub (;$$) :lvalue :Gazebo((>:O)) {
474 # vvv only if check_argument_count is enabled vvv
475 Carp::croak "Not enough arguments for fun (anon)" if @_ < 2;
476 Carp::croak "Too many arguments for fun (anon)" if @_ > 2;
7817d698 477 # ^^^ ^^^
698e861c 478 my ($p, $q) = @_;
63a24d7c 479 ...
480 };
481
482=head2 Wrapping Function::Parameters
125c067e 483
db81d362 484If you want to wrap L<Function::Parameters>, you just have to call its
485C<import> method. It always applies to the file that is currently being parsed
95915793 486and its effects are L<lexical|perlpragma> (i.e. it works like L<warnings> or
487L<strict>).
63a24d7c 488
489 package Some::Wrapper;
490 use Function::Parameters ();
491 sub import {
492 Function::Parameters->import;
698e861c 493 # or Function::Parameters->import(@custom_import_args);
63a24d7c 494 }
eeb7df5f 495
7a63380c 496=head1 AUTHOR
497
498Lukas Mai, C<< <l.mai at web.de> >>
499
500=head1 COPYRIGHT & LICENSE
501
db81d362 502Copyright 2010, 2011, 2012 Lukas Mai.
7a63380c 503
504This program is free software; you can redistribute it and/or modify it
505under the terms of either: the GNU General Public License as published
506by the Free Software Foundation; or the Artistic License.
507
508See http://dev.perl.org/licenses/ for more information.
509
510=cut