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, $proto_type) = @$item;
49 _assert_valid_identifier $name;
51 unless (ref $proto_type) {
52 # use '||' instead of 'or' to preserve $proto_type in the error message
53 $proto_type = $type_map{$proto_type}
54 || confess qq["$proto_type" doesn't look like a valid type (one of ${\join ', ', sort keys %type_map})];
56 my %type = %$proto_type;
58 $clean{name} = delete $type{name} || 'optional';
59 $clean{name} =~ /^(?:optional|required|prohibited)\z/
60 or confess qq["$clean{name}" doesn't look like a valid name attribute (one of optional, required, prohibited)];
61 $clean{shift} = delete $type{shift} || '';
63 _assert_valid_identifier $clean{shift}, 1;
64 bytes::length($clean{shift}) < SHIFT_NAME_LIMIT
65 or confess qq["$clean{shift}" is longer than I can handle];
68 %type and confess "Invalid keyword property: @{[keys %type]}";
70 $spec{$name} = \%clean;
73 for my $kw (keys %spec) {
74 my $type = $spec{$kw};
76 $^H{HINTK_SHIFT_ . $kw} = $type->{shift};
77 $^H{HINTK_NAME_ . $kw} =
78 $type->{name} eq 'prohibited' ? FLAG_NAME_PROHIBITED :
79 $type->{name} eq 'required' ? FLAG_NAME_REQUIRED :
82 $^H{+HINTK_KEYWORDS} .= "$kw ";
90 delete $^H{+HINTK_KEYWORDS};
95 $^H{+HINTK_KEYWORDS} =~ s/(?<![^ ])\Q$kw\E //g;
112 Function::Parameters - subroutine definitions with parameter lists
116 use Function::Parameters;
118 fun foo($bar, $baz) {
122 fun mymap($fun, @args) :(&@) {
125 push @res, $fun->($_);
130 print "$_\n" for mymap { $_ * 2 } 1 .. 4;
132 method set_name($name) {
133 $self->{name} = $name;
140 use Function::Parameters {
145 my $f = proc ($x) { $x * 2 };
152 This module lets you use parameter lists in your subroutines. Thanks to
153 L<PL_keyword_plugin|perlapi/PL_keyword_plugin> it works without source filters.
155 WARNING: This is my first attempt at writing L<XS code|perlxs> and I have
156 almost no experience with perl's internals. So while this module might
157 appear to work, it could also conceivably make your programs segfault.
158 Consider this module alpha quality.
162 To use this new functionality, you have to use C<fun> instead of C<sub> -
163 C<sub> continues to work as before. The syntax is almost the same as for
164 C<sub>, but after the subroutine name (or directly after C<fun> if you're
165 writing an anonymous sub) you can write a parameter list in parentheses. This
166 list consists of comma-separated variables.
168 The effect of C<fun foo($bar, $baz) {> is as if you'd written
169 C<sub foo { my ($bar, $baz) = @_; >, i.e. the parameter list is simply
170 copied into C<my> and initialized from L<@_|perlvar/"@_">.
172 In addition you can use C<method>, which understands the same syntax as C<fun>
173 but automatically creates a C<$self> variable for you. So by writing
174 C<method foo($bar, $baz) {> you get the same effect as
175 C<sub foo { my $self = shift; my ($bar, $baz) = @_; >.
177 =head2 Customizing the generated keywords
179 You can customize the names of the keywords injected into your scope. To do
180 that you pass a hash reference in the import list:
182 use Function::Parameters { proc => 'function', meth => 'method' }; # -or-
183 use Function::Parameters { proc => 'function' }; # -or-
184 use Function::Parameters { meth => 'method' };
186 The first line creates two keywords, C<proc> and C<meth> (for defining
187 functions and methods, respectively). The last two lines only create one
188 keyword. Generally the hash keys can be any identifiers you want while the
189 values have to be either C<function>, C<method>, or a hash reference (see
190 below). The difference between C<function> and C<method> is that C<method>s
191 automatically L<shift|perlfunc/shift> their first argument into C<$self>.
193 The following shortcuts are available:
195 use Function::Parameters;
197 use Function::Parameters { fun => 'function', method => 'method' };
203 The following shortcuts are deprecated and may be removed from a future version
207 use Function::Parameters 'foo';
209 use Function::Parameters { 'foo' => 'function' };
216 use Function::Parameters 'foo', 'bar';
218 use Function::Parameters { 'foo' => 'function', 'bar' => 'method' };
220 That is, if you want to pass arguments to L<Function::Parameters>, use a
221 hashref, not a list of strings.
223 You can customize things even more by passing a hashref instead of C<function>
224 or C<method>. This hash can have the following keys:
230 Valid values: C<optional> (default), C<required> (all uses of this keyword must
231 specify a function name), and C<prohibited> (all uses of this keyword must not
232 specify a function name). This means a C<< name => 'prohibited' >> keyword can
233 only be used for defining anonymous functions.
237 Valid values: strings that look like a scalar variable. Any function created by
238 this keyword will automatically L<shift|perlfunc/shift> its first argument into
239 a local variable whose name is specified here.
243 Plain C<'function'> is equivalent to C<< { name => 'optional' } >>, and plain
244 C<'method'> is equivalent to C<< { name => 'optional', shift => '$self' } >>.
246 =head2 Syntax and generated code
248 Normally, Perl subroutines are not in scope in their own body, meaning the
249 parser doesn't know the name C<foo> or its prototype while processing the body
250 of C<sub foo ($) { foo $bar[1], $bar[0]; }>, parsing it as
251 C<$bar-E<gt>foo([1], $bar[0])>. Yes. You can add parens to change the
252 interpretation of this code, but C<foo($bar[1], $bar[0])> will only trigger
253 a I<foo() called too early to check prototype> warning. This module attempts
254 to fix all of this by adding a subroutine declaration before the definition,
255 so the parser knows the name (and possibly prototype) while it processes the
256 body. Thus C<fun foo($x) :($) { $x }> really turns into
257 C<sub foo ($); sub foo ($) { my ($x) = @_; $x }>.
259 If you need L<subroutine attributes|perlsub/"Subroutine Attributes">, you can
260 put them after the parameter list with their usual syntax.
262 Syntactically, these new parameter lists live in the spot normally occupied
263 by L<prototypes|perlsub/"Prototypes">. However, you can include a prototype by
264 specifying it as the first attribute (this is syntactically unambiguous
265 because normal attributes have to start with a letter while a prototype starts
268 As an example, the following declaration uses every feature available
269 (subroutine name, parameter list, prototype, attributes, and implicit
272 method foo($x, $y, @z) :($;$@) :lvalue :Banana(2 + 2) {
276 And here's what it turns into:
278 sub foo ($;$@); sub foo ($;$@) :lvalue :Banana(2 + 2) { my $self = shift; my ($x, $y, @z) = @_;
284 my $coderef = fun ($p, $q) :(;$$)
290 And the generated code:
292 my $coderef = sub (;$$) :lvalue :Gazebo((>:O)) { my ($p, $q) = @_;
296 =head2 Wrapping Function::Parameters
298 If you want to wrap L<Function::Parameters>, you just have to call its
299 C<import> method. It always applies to the file that is currently being parsed
300 and its effects are lexical (i.e. it works like L<warnings> or L<strict>):
302 package Some::Wrapper;
303 use Function::Parameters ();
305 Function::Parameters->import;
306 # or Function::Parameters->import(@other_import_args);
311 Lukas Mai, C<< <l.mai at web.de> >>
313 =head1 COPYRIGHT & LICENSE
315 Copyright 2010, 2011, 2012 Lukas Mai.
317 This program is free software; you can redistribute it and/or modify it
318 under the terms of either: the GNU General Public License as published
319 by the Free Software Foundation; or the Artistic License.
321 See http://dev.perl.org/licenses/ for more information.