1 package Function::Parameters;
10 our $VERSION = '0.05_02';
14 use B::Hooks::EndOfScope qw(on_scope_end);
18 sub _assert_valid_identifier {
19 my ($name, $with_dollar) = @_;
20 my $bonus = $with_dollar ? '\$' : '';
21 $name =~ /^${bonus}[^\W\d]\w*\z/
22 or confess qq{"$name" doesn't look like a valid identifier};
25 my @bare_arms = qw(function method);
27 function => { name => 'optional' },
28 method => { name => 'optional', shift => '$self' },
34 @_ or @_ = ('fun', 'method');
35 if (@_ == 1 && ref($_[0]) eq 'HASH') {
36 @_ = map [$_, $_[0]{$_}], keys %{$_[0]}
46 : [$proto, $bare_arms[$bare++] || confess(qq{Don't know what to do with "$proto"})]
48 my ($name, $type) = @$item;
49 _assert_valid_identifier $name;
52 # use '||' instead of 'or' to preserve $type in the error message
53 $type = $type_map{$type}
54 || confess qq["$type" doesn't look like a valid type (one of ${\join ', ', sort keys %type_map})];
56 $type->{name} ||= 'optional';
57 $type->{name} =~ /^(?:optional|required|prohibited)\z/
58 or confess qq["$type->{name}" doesn't look like a valid name attribute (one of optional, required, prohibited)];
60 _assert_valid_identifier $type->{shift}, 1;
61 bytes::length($type->{shift}) < SHIFT_NAME_LIMIT
62 or confess qq["$type->{shift}" is longer than I can handle];
68 for my $kw (keys %spec) {
69 my $type = $spec{$kw};
71 $^H{HINTK_SHIFT_ . $kw} = $type->{shift} || '';
72 $^H{HINTK_NAME_ . $kw} =
73 $type->{name} eq 'prohibited' ? FLAG_NAME_PROHIBITED :
74 $type->{name} eq 'required' ? FLAG_NAME_REQUIRED :
77 $^H{+HINTK_KEYWORDS} .= "$kw ";
85 delete $^H{+HINTK_KEYWORDS};
90 $^H{+HINTK_KEYWORDS} =~ s/(?<![^ ])\Q$kw\E //g;
107 Function::Parameters - subroutine definitions with parameter lists
111 use Function::Parameters;
113 fun foo($bar, $baz) {
117 fun mymap($fun, @args) :(&@) {
120 push @res, $fun->($_);
125 print "$_\n" for mymap { $_ * 2 } 1 .. 4;
127 method set_name($name) {
128 $self->{name} = $name;
135 use Function::Parameters {
140 my $f = proc ($x) { $x * 2 };
147 This module lets you use parameter lists in your subroutines. Thanks to
148 L<PL_keyword_plugin|perlapi/PL_keyword_plugin> it works without source filters.
150 WARNING: This is my first attempt at writing L<XS code|perlxs> and I have
151 almost no experience with perl's internals. So while this module might
152 appear to work, it could also conceivably make your programs segfault.
153 Consider this module alpha quality.
157 To use this new functionality, you have to use C<fun> instead of C<sub> -
158 C<sub> continues to work as before. The syntax is almost the same as for
159 C<sub>, but after the subroutine name (or directly after C<fun> if you're
160 writing an anonymous sub) you can write a parameter list in parentheses. This
161 list consists of comma-separated variables.
163 The effect of C<fun foo($bar, $baz) {> is as if you'd written
164 C<sub foo { my ($bar, $baz) = @_; >, i.e. the parameter list is simply
165 copied into C<my> and initialized from L<@_|perlvar/"@_">.
167 In addition you can use C<method>, which understands the same syntax as C<fun>
168 but automatically creates a C<$self> variable for you. So by writing
169 C<method foo($bar, $baz) {> you get the same effect as
170 C<sub foo { my $self = shift; my ($bar, $baz) = @_; >.
172 =head2 Customizing the generated keywords
174 You can customize the names of the keywords injected into your scope. To do
175 that you pass a hash reference in the import list:
177 use Function::Parameters { proc => 'function', meth => 'method' }; # -or-
178 use Function::Parameters { proc => 'function' }; # -or-
179 use Function::Parameters { meth => 'method' };
181 The first line creates two keywords, C<proc> and C<meth> (for defining
182 functions and methods, respectively). The last two lines only create one
183 keyword. Generally the hash keys can be any identifiers you want while the
184 values have to be either C<function>, C<method>, or a hash reference (see
185 below). The difference between C<function> and C<method> is that C<method>s
186 automatically L<shift|perlfunc/shift> their first argument into C<$self>.
188 The following shortcuts are available:
190 use Function::Parameters;
192 use Function::Parameters { fun => 'function', method => 'method' };
198 The following shortcuts are deprecated and may be removed from a future version
202 use Function::Parameters 'foo';
204 use Function::Parameters { 'foo' => 'function' };
211 use Function::Parameters 'foo', 'bar';
213 use Function::Parameters { 'foo' => 'function', 'bar' => 'method' };
215 That is, if you want to pass arguments to L<Function::Parameters>, use a
216 hashref, not a list of strings.
218 You can customize things even more by passing a hashref instead of C<function>
219 or C<method>. This hash can have the following keys:
225 Valid values: C<optional> (default), C<required> (all uses of this keyword must
226 specify a function name), and C<prohibited> (all uses of this keyword must not
227 specify a function name). This means a C<< name => 'prohibited' >> keyword can
228 only be used for defining anonymous functions.
232 Valid values: strings that look like a scalar variable. Any function created by
233 this keyword will automatically L<shift|perlfunc/shift> its first argument into
234 a local variable whose name is specified here.
238 Plain C<'function'> is equivalent to C<< { name => 'optional' } >>, and plain
239 C<'method'> is equivalent to C<< { name => 'optional', shift => '$self' } >>.
241 =head2 Syntax and generated code
243 Normally, Perl subroutines are not in scope in their own body, meaning the
244 parser doesn't know the name C<foo> or its prototype while processing the body
245 of C<sub foo ($) { foo $bar[1], $bar[0]; }>, parsing it as
246 C<$bar-E<gt>foo([1], $bar[0])>. Yes. You can add parens to change the
247 interpretation of this code, but C<foo($bar[1], $bar[0])> will only trigger
248 a I<foo() called too early to check prototype> warning. This module attempts
249 to fix all of this by adding a subroutine declaration before the definition,
250 so the parser knows the name (and possibly prototype) while it processes the
251 body. Thus C<fun foo($x) :($) { $x }> really turns into
252 C<sub foo ($); sub foo ($) { my ($x) = @_; $x }>.
254 If you need L<subroutine attributes|perlsub/"Subroutine Attributes">, you can
255 put them after the parameter list with their usual syntax.
257 Syntactically, these new parameter lists live in the spot normally occupied
258 by L<prototypes|perlsub/"Prototypes">. However, you can include a prototype by
259 specifying it as the first attribute (this is syntactically unambiguous
260 because normal attributes have to start with a letter while a prototype starts
263 As an example, the following declaration uses every feature available
264 (subroutine name, parameter list, prototype, attributes, and implicit
267 method foo($x, $y, @z) :($;$@) :lvalue :Banana(2 + 2) {
271 And here's what it turns into:
273 sub foo ($;$@); sub foo ($;$@) :lvalue :Banana(2 + 2) { my $self = shift; my ($x, $y, @z) = @_;
279 my $coderef = fun ($p, $q) :(;$$)
285 And the generated code:
287 my $coderef = sub (;$$) :lvalue :Gazebo((>:O)) { my ($p, $q) = @_;
291 =head2 Wrapping Function::Parameters
293 If you want to wrap L<Function::Parameters>, you just have to call its
294 C<import> method. It always applies to the file that is currently being parsed
295 and its effects are lexical (i.e. it works like L<warnings> or L<strict>):
297 package Some::Wrapper;
298 use Function::Parameters ();
300 Function::Parameters->import;
301 # or Function::Parameters->import(@other_import_args);
306 Lukas Mai, C<< <l.mai at web.de> >>
308 =head1 COPYRIGHT & LICENSE
310 Copyright 2010, 2011, 2012 Lukas Mai.
312 This program is free software; you can redistribute it and/or modify it
313 under the terms of either: the GNU General Public License as published
314 by the Free Software Foundation; or the Artistic License.
316 See http://dev.perl.org/licenses/ for more information.