X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FFunction%2FParameters.pm;h=2e2f5807dc349dff79c66746edb4e7aea3bf9078;hb=e33f970b8bfb0949fc5effea46239ca92d59c2d8;hp=c3d71255e118777e48b475eaced15d6ac86043e5;hpb=fcaf7811b0caec1b00651fbcf9d1915fe1be008f;p=p5sagit%2FFunction-Parameters.git diff --git a/lib/Function/Parameters.pm b/lib/Function/Parameters.pm index c3d7125..2e2f580 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.09'; + our $VERSION = '0.10'; XSLoader::load; } @@ -39,6 +39,7 @@ my %type_map = ( check_argument_count => 0, attrs => ':method', shift => '$self', + invocant => 1, }, classmethod => { name => 'optional', @@ -46,6 +47,7 @@ my %type_map = ( check_argument_count => 0, attributes => ':method', shift => '$class', + invocant => 1, }, ); for my $k (keys %type_map) { @@ -110,6 +112,7 @@ sub import { : 1 ; $clean{check_argument_count} = !!delete $type{check_argument_count}; + $clean{invocant} = !!delete $type{invocant}; %type and confess "Invalid keyword property: @{[keys %type]}"; @@ -126,6 +129,7 @@ sub import { ; $flags |= FLAG_DEFAULT_ARGS if $type->{default_arguments}; $flags |= FLAG_CHECK_NARGS if $type->{check_argument_count}; + $flags |= FLAG_INVOCANT if $type->{invocant}; $^H{HINTK_FLAGS_ . $kw} = $flags; $^H{HINTK_SHIFT_ . $kw} = $type->{shift}; $^H{HINTK_ATTRS_ . $kw} = $type->{attrs}; @@ -183,12 +187,17 @@ Function::Parameters - subroutine definitions with parameter lists method set_name($name) { $self->{name} = $name; } - + + # method with explicit invocant + method new($class: %init) { + return bless { %init }, $class; + } + # function with default arguments fun search($haystack, $needle = qr/^(?!)/, $offset = 0) { ... } - + # method with default arguments method skip($amount = 1) { $self->{position} += $amount; @@ -198,6 +207,22 @@ Function::Parameters - subroutine definitions with parameter lists =pod + use Function::Parameters qw(:strict); + + fun greet($x) { + print "Hello, $x\n"; + } + + greet "foo", "bar"; + # Dies at runtime with "Too many arguments for fun greet" + + greet; + # Dies at runtime with "Not enough arguments for fun greet" + +=cut + +=pod + # use different keywords use Function::Parameters { proc => 'function', @@ -214,11 +239,6 @@ Function::Parameters - subroutine definitions with parameter lists This module lets you use parameter lists in your subroutines. Thanks to L it works without source filters. -WARNING: This is my first attempt at writing L and I have -almost no experience with perl's internals. So while this module might -appear to work, it could also conceivably make your programs segfault. -Consider this module alpha quality. - =head2 Basic stuff To use this new functionality, you have to use C instead of C - @@ -318,6 +338,17 @@ Valid values: strings that look like a scalar variable. Any function created by this keyword will automatically L its first argument into a local variable whose name is specified here. +=item C + +Valid values: booleans. This lets users of this keyword specify an explicit +invocant, that is, the first parameter may be followed by a C<:> (colon) +instead of a comma and will by initialized by shifting the first element off +C<@_>. + +You can combine C and C, in which case the variable named in +C serves as a default shift target for functions that don't specify an +explicit invocant. + =item C, C Valid values: strings that are valid source code for attributes. Any value @@ -412,6 +443,7 @@ C<'method'> is equivalent to: check_argument_count => 0, attributes => ':method', shift => '$self', + invocant => 1, } C<'method_strict'> is like C<'method'> but with @@ -425,6 +457,7 @@ C<'classmethod'> is equivalent to: check_argument_count => 0, attributes => ':method', shift => '$class', + invocant => 1, } C<'classmethod_strict'> is like C<'classmethod'> but with @@ -454,9 +487,10 @@ with C<(>). 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>): +attributes, attributes, argument count checks, and implicit C<$self> overriden +by an explicit invocant declaration): - method foo($x, $y, $z = sqrt 5) + method foo($this: $x, $y, $z = sqrt 5) :($$$;$) :lvalue :Banana(2 + 2) @@ -470,7 +504,7 @@ And here's what it turns into: sub foo ($$$;$); Carp::croak "Not enough arguments for method foo" if @_ < 3; Carp::croak "Too many arguments for method foo" if @_ > 4; - my $self = shift; + my $this = shift; my ($x, $y, $z) = @_; $z = sqrt 5 if @_ < 3; ...