X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FFunction%2FParameters.pm;h=c87f78eecd2f2d0ab62b9409554eb61ec89ec571;hb=929a23c5b4a988198111135a0922625ab77e5cd9;hp=b0d2b2b566880cc0ce0ecaaea952a6777ec8cf9c;hpb=698e861c059c83b38a1678b02a32ff40386cac58;p=p5sagit%2FFunction-Parameters.git diff --git a/lib/Function/Parameters.pm b/lib/Function/Parameters.pm index b0d2b2b..c87f78e 100644 --- a/lib/Function/Parameters.pm +++ b/lib/Function/Parameters.pm @@ -9,7 +9,7 @@ use Carp qw(confess); use XSLoader; BEGIN { - our $VERSION = '0.06'; + our $VERSION = '0.09'; XSLoader::load; } @@ -48,6 +48,12 @@ my %type_map = ( shift => '$class', }, ); +for my $k (keys %type_map) { + $type_map{$k . '_strict'} = { + %{$type_map{$k}}, + check_argument_count => 1, + }; +} sub import { my $class = shift; @@ -154,7 +160,9 @@ Function::Parameters - subroutine definitions with parameter lists } # function with prototype - fun mymap($fun, @args) :(&@) { + fun mymap($fun, @args) + :(&@) + { my @res; for (@args) { push @res, $fun->($_); @@ -214,7 +222,7 @@ list consists of comma-separated variables. The effect of C is as if you'd written C, i.e. the parameter list is simply -copied into L and initialized from L<@_|perlvar/"@_">. +copied into L and initialized from L<@_|perlvar/"@_">. In addition you can use C, which understands the same syntax as C but automatically creates a C<$self> variable for you. So by writing @@ -242,8 +250,9 @@ Or more concretely: The first line creates two keywords, C and C (for defining functions and methods, respectively). The last two lines only create one keyword. Generally the hash keys (keywords) can be any identifiers you want -while the values (types) have to be either C<'function'>, C<'method'>, -C<'classmethod'>, or a hash reference (see below). The main difference between +while the values (types) have to be either a hash reference (see below) or +C<'function'>, C<'method'>, C<'classmethod'>, C<'function_strict'>, +C<'method_strict'>, or C<'classmethod_strict'>. The main difference between C<'function'> and C<'method'> is that C<'method'>s automatically L their first argument into C<$self> (C<'classmethod'>s are similar but shift into C<$class>). @@ -336,18 +345,15 @@ turns into ... } -except that none of the parameters are in scope in the expressions that specify -default values. Thus: +You can even refer to previous parameters in the same parameter list: - my $var = "outer"; + print fun ($x, $y = $x + 1) { "$x and $y" }->(9); # "9 and 10" - fun foo($var, $wat = $var) { - # $wat will default to "outer", not to what was passed - # as the first argument! - ... - } +This also works with the implicit first parameter of methods: -This may change in a future version of this module. + method scale($factor = $self->default_factor) { + $self->{amount} *= $factor; + } =item C @@ -382,6 +388,9 @@ Plain C<'function'> is equivalent to: (These are all default values so C<'function'> is also equivalent to C<{}>.) +C<'function_strict'> is like C<'function'> but with +C<< check_argument_count => 1 >>. + C<'method'> is equivalent to: { @@ -392,6 +401,9 @@ C<'method'> is equivalent to: shift => '$self', } +C<'method_strict'> is like C<'method'> but with +C<< check_argument_count => 1 >>. + C<'classmethod'> is equivalent to: { @@ -402,6 +414,9 @@ C<'classmethod'> is equivalent to: shift => '$class', } +C<'classmethod_strict'> is like C<'classmethod'> but with +C<< check_argument_count => 1 >>. + =head2 Syntax and generated code Normally, Perl subroutines are not in scope in their own body, meaning the @@ -415,7 +430,7 @@ so the parser knows the name (and possibly prototype) while it processes the body. Thus C really turns into C. -If you need L, you can +If you need L, you can put them after the parameter list with their usual syntax. Syntactically, these new parameter lists live in the spot normally occupied @@ -428,7 +443,11 @@ As an example, the following declaration uses every available feature (subroutine name, parameter list, default arguments, prototype, default attributes, attributes, argument count checks, and implicit C<$self>): - method foo($x, $y, $z = sqrt 5) :($$$;$) :lvalue :Banana(2 + 2) { + method foo($x, $y, $z = sqrt 5) + :($$$;$) + :lvalue + :Banana(2 + 2) + { ... } @@ -446,7 +465,8 @@ And here's what it turns into: Another example: - my $coderef = fun ($p, $q) :(;$$) + my $coderef = fun ($p, $q) + :(;$$) :lvalue :Gazebo((>:O)) { ... @@ -458,6 +478,7 @@ And the generated code: # vvv only if check_argument_count is enabled vvv Carp::croak "Not enough arguments for fun (anon)" if @_ < 2; Carp::croak "Too many arguments for fun (anon)" if @_ > 2; + # ^^^ ^^^ my ($p, $q) = @_; ... }; @@ -466,7 +487,8 @@ And the generated code: If you want to wrap L, you just have to call its C method. It always applies to the file that is currently being parsed -and its effects are lexical (i.e. it works like L or L): +and its effects are L (i.e. it works like L or +L). package Some::Wrapper; use Function::Parameters ();