1 package Function::Parameters;
8 our $VERSION = '0.05_01';
12 use B::Hooks::EndOfScope qw(on_scope_end);
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};
23 my @bare_arms = qw(function method);
25 function => { name => 'optional' },
26 method => { name => 'optional', shift => '$self' },
32 @_ or @_ = ('fun', 'method');
33 if (@_ == 1 && ref($_[0]) eq 'HASH') {
34 @_ = map [$_, $_[0]{$_}], keys %{$_[0]}
44 : [$proto, $bare_arms[$bare++] || confess(qq{Don't know what to do with "$proto"})]
46 my ($name, $type) = @$item;
47 _assert_valid_identifier $name;
50 # use '||' instead of 'or' to preserve $type in the error message
51 $type = $type_map{$type}
52 || confess qq["$type" doesn't look like a valid type (one of ${\join ', ', sort keys %type_map})];
54 $type->{name} ||= 'optional';
55 $type->{name} =~ /^(?:optional|required|prohibited)\z/
56 or confess qq["$type->{name}" doesn't look like a valid name attribute (one of optional, required, prohibited)];
58 _assert_valid_identifier $type->{shift}, 1;
59 bytes::length($type->{shift}) < SHIFT_NAME_LIMIT
60 or confess qq["$type->{shift}" is longer than I can handle];
66 for my $kw (keys %spec) {
67 my $type = $spec{$kw};
69 $^H{HINTK_SHIFT_ . $kw} = $type->{shift} || '';
70 $^H{HINTK_NAME_ . $kw} =
71 $type->{name} eq 'prohibited' ? FLAG_NAME_PROHIBITED :
72 $type->{name} eq 'required' ? FLAG_NAME_REQUIRED :
75 $^H{+HINTK_KEYWORDS} .= "$kw ";
83 delete $^H{+HINTK_KEYWORDS};
88 $^H{+HINTK_KEYWORDS} =~ s/(?<![^ ])\Q$kw\E //g;
105 Function::Parameters - subroutine definitions with parameter lists
109 use Function::Parameters;
111 fun foo($bar, $baz) {
115 fun mymap($fun, @args) :(&@) {
118 push @res, $fun->($_);
123 print "$_\n" for mymap { $_ * 2 } 1 .. 4;
125 method set_name($name) {
126 $self->{name} = $name;
133 use Function::Parameters 'proc', 'meth';
135 my $f = proc ($x) { $x * 2 };
142 This module lets you use parameter lists in your subroutines. Thanks to
143 L<perlapi/PL_keyword_plugin> it works without source filters.
145 WARNING: This is my first attempt at writing L<XS code|perlxs> and I have
146 almost no experience with perl's internals. So while this module might
147 appear to work, it could also conceivably make your programs segfault.
148 Consider this module alpha quality.
152 To use this new functionality, you have to use C<fun> instead of C<sub> -
153 C<sub> continues to work as before. The syntax is almost the same as for
154 C<sub>, but after the subroutine name (or directly after C<fun> if you're
155 writing an anonymous sub) you can write a parameter list in parentheses. This
156 list consists of comma-separated variables.
158 The effect of C<fun foo($bar, $baz) {> is as if you'd written
159 C<sub foo { my ($bar, $baz) = @_; >, i.e. the parameter list is simply
160 copied into C<my> and initialized from L<@_|perlvar/"@_">.
162 In addition you can use C<method>, which understands the same syntax as C<fun>
163 but automatically creates a C<$self> variable for you. So by writing
164 C<method foo($bar, $baz) {> you get the same effect as
165 C<sub foo { my $self = shift; my ($bar, $baz) = @_; >.
167 =head2 Customizing the generated keywords
169 You can customize the names of the keywords injected in your package. To do that
170 you pass a hash reference in the import list:
172 use Function::Parameters { proc => 'function', meth => 'method' }; # -or-
173 use Function::Parameters { proc => 'function' }; # -or-
174 use Function::Parameters { meth => 'method' };
176 The first line creates two keywords, C<proc> and C<meth> (for defining
177 functions and methods, respectively). The last two lines only create one
178 keyword. Generally the hash keys can be any identifiers you want while the
179 values have to be either C<function>, C<method>, or a hash reference (see
180 below). The difference between C<function> and C<method> is that C<method>s
181 automatically L<shift|perlfunc/shift> their first argument into C<$self>.
183 The following shortcuts are available:
185 use Function::Parameters;
187 use Function::Parameters { fun => 'function', method => 'method' };
193 use Function::Parameters 'foo';
195 use Function::Parameters { 'foo' => 'function' };
201 use Function::Parameters 'foo', 'bar';
203 use Function::Parameters { 'foo' => 'function', 'bar' => 'method' };
205 You can customize things even more by passing a hashref instead of C<function>
206 or C<method>. This hash can have the following keys:
212 Valid values: C<optional> (default), C<required> (all uses of this keyword must
213 specify a function name), and C<prohibited> (all uses of this keyword must not
214 specify a function name). This means a C<< name => 'prohibited' >> keyword can
215 only be used for defining anonymous functions.
219 Valid values: strings that look like a scalar variable. Any function created by
220 this keyword will automatically L<shift|perlfunc/shift> its first argument into
221 a local variable with the name specified here.
225 Plain C<function> is equivalent to C<< { name => 'optional' } >>, and plain
226 C<method> is equivalent to C<< { name => 'optional', shift => '$self'} >>.
228 =head2 Other advanced stuff
230 Normally, Perl subroutines are not in scope in their own body, meaning the
231 parser doesn't know the name C<foo> or its prototype while processing
232 C<sub foo ($) { foo $bar[1], $bar[0]; }>, parsing it as
233 C<$bar-E<gt>foo([1], $bar[0])>. Yes. You can add parens to change the
234 interpretation of this code, but C<foo($bar[1], $bar[0])> will only trigger
235 a I<foo() called too early to check prototype> warning. This module attempts
236 to fix all of this by adding a subroutine declaration before the definition,
237 so the parser knows the name (and possibly prototype) while it processes the
238 body. Thus C<fun foo($x) :($) { $x }> really turns into
239 C<sub foo ($); sub foo ($) { my ($x) = @_; $x }>.
241 If you need L<subroutine attributes|perlsub/"Subroutine Attributes">, you can
242 put them after the parameter list with their usual syntax.
244 Syntactically, these new parameter lists live in the spot normally occupied
245 by L<prototypes|perlsub/"Prototypes">. However, you can include a prototype by
246 specifying it as the first attribute (this is syntactically unambiguous
247 because normal attributes have to start with a letter).
249 If you want to wrap L<Function::Parameters>, you just have to call its
250 C<import> method. It always applies to the file that is currently being parsed
251 and its effects are lexical (i.e. it works like L<warnings> or L<strict>);
253 package Some::Wrapper;
254 use Function::Parameters ();
256 Function::Parameters->import;
257 # or Function::Parameters->import(@other_import_args);
262 Lukas Mai, C<< <l.mai at web.de> >>
264 =head1 COPYRIGHT & LICENSE
266 Copyright 2010, 2011, 2012 Lukas Mai.
268 This program is free software; you can redistribute it and/or modify it
269 under the terms of either: the GNU General Public License as published
270 by the Free Software Foundation; or the Artistic License.
272 See http://dev.perl.org/licenses/ for more information.