use XSLoader;
BEGIN {
- our $VERSION = '1.00';
+ our $VERSION = '1.0103';
XSLoader::load;
}
default_arguments => 1,
check_argument_count => 0,
named_parameters => 1,
+ types => 1,
},
method => {
name => 'optional',
default_arguments => 1,
check_argument_count => 0,
named_parameters => 1,
+ types => 1,
attrs => ':method',
shift => '$self',
invocant => 1,
default_arguments => 1,
check_argument_count => 0,
named_parameters => 1,
+ types => 1,
attributes => ':method',
shift => '$class',
invocant => 1,
$clean{check_argument_count} = !!delete $type{check_argument_count};
$clean{invocant} = !!delete $type{invocant};
$clean{named_parameters} = !!delete $type{named_parameters};
+ $clean{types} = !!delete $type{types};
%type and confess "Invalid keyword property: @{[keys %type]}";
FLAG_ANON_OK | FLAG_NAME_OK
;
$flags |= FLAG_DEFAULT_ARGS if $type->{default_arguments};
- $flags |= FLAG_CHECK_NARGS if $type->{check_argument_count};
+ $flags |= FLAG_CHECK_NARGS | FLAG_CHECK_TARGS if $type->{check_argument_count};
$flags |= FLAG_INVOCANT if $type->{invocant};
$flags |= FLAG_NAMED_PARAMS if $type->{named_parameters};
+ $flags |= FLAG_TYPES_OK if $type->{types};
$^H{HINTK_FLAGS_ . $kw} = $flags;
$^H{HINTK_SHIFT_ . $kw} = $type->{shift};
$^H{HINTK_ATTRS_ . $kw} = $type->{attrs};
$key,
$declarator,
$invocant,
+ $invocant_type,
$positional_required,
$positional_optional,
$named_required,
$named_optional,
$slurpy,
+ $slurpy_type,
) = @_;
- my $blob = pack '(Z*)*',
- $declarator,
- $invocant // '',
- join(' ', @$positional_required),
- join(' ', @$positional_optional),
- join(' ', @$named_required),
- join(' ', @$named_optional),
- $slurpy // '',
- ;
-
- $metadata{$key} = $blob;
+ my $info = {
+ declarator => $declarator,
+ invocant => defined $invocant ? [$invocant, $invocant_type] : undef,
+ slurpy => defined $slurpy ? [$slurpy , $slurpy_type ] : undef,
+ positional_required => $positional_required,
+ positional_optional => $positional_optional,
+ named_required => $named_required,
+ named_optional => $named_optional,
+ };
+
+ $metadata{$key} = $info;
+}
+
+sub _mkparam1 {
+ my ($pair) = @_;
+ my ($v, $t) = @{$pair || []} or return undef;
+ Function::Parameters::Param->new(
+ name => $v,
+ type => $t,
+ )
+}
+
+sub _mkparams {
+ my @r;
+ while (my ($v, $t) = splice @_, 0, 2) {
+ push @r, Function::Parameters::Param->new(
+ name => $v,
+ type => $t,
+ );
+ }
+ \@r
}
sub info {
my ($func) = @_;
my $key = _cv_root $func or return undef;
- my $blob = $metadata{$key} or return undef;
- my @info = unpack '(Z*)*', $blob;
+ my $info = $metadata{$key} or return undef;
require Function::Parameters::Info;
Function::Parameters::Info->new(
- keyword => $info[0],
- invocant => $info[1] || undef,
- _positional_required => [split ' ', $info[2]],
- _positional_optional => [split ' ', $info[3]],
- _named_required => [split ' ', $info[4]],
- _named_optional => [split ' ', $info[5]],
- slurpy => $info[6] || undef,
+ keyword => $info->{declarator},
+ invocant => _mkparam1($info->{invocant}),
+ slurpy => _mkparam1($info->{slurpy}),
+ (map +("_$_" => _mkparams @{$info->{$_}}), glob '{positional,named}_{required,optional}')
)
}
function, and returns either C<undef> (if it knows nothing about the function)
or a L<Function::Parameters::Info> object describing the parameter list.
+Note: This feature is implemented using L<Moo>, so you'll need to have L<Moo>
+installed if you want to call C<Function::Parameters::info> (alternatively, if
+L<Moose> is already loaded by the time C<Function::Parameters::info> is first
+called, it will use that instead).
+
See L<Function::Parameters::Info> for examples.
=head2 Wrapping C<Function::Parameters>
# or Function::Parameters->import(@custom_import_args);
}
+=head2 Experimental feature: Types
+
+An experimental feature is now available: You can annotate parameters with
+L<Moose types|Moose::Manual::Types>. That is, before each parameter you can put
+a type specification consisting of identifiers (C<Foo>), unions (C<... | ...>),
+and parametric types (C<...[...]>). Example:
+
+ fun foo(Int $n, ArrayRef[String | CodeRef] $cb) { ... }
+
+If you do this, L<Moose> will be loaded automatically (if that hasn't happened
+yet). These specifications are parsed and validated using
+L<C<Moose::Util::TypeConstraints::find_or_parse_type_constraint>|Moose::Util::TypeConstraints/find_or_parse_type_constraint>.
+
+If you are in "lax" mode, nothing further happens and the types are ignored. If
+you are in "strict" mode, C<Function::Parameters> generates code to make sure
+any values passed in conform to the type (via
+L<< C<< $constraint->check($value) >>|Moose::Meta::TypeConstraint/$constraint->check($value) >>).
+
+In addition, these type constraints are inspectable through the
+L<Function::Parameters::Info> object returned by
+L<C<Function::Parameters::info>|/Introspection>.
+
+=head2 Experimental experimental feature: Type expressions
+
+An even more experimental feature is the ability to specify arbitrary
+expressions as types. The syntax for this is like the literal types described
+above, but with an expression wrapped in parentheses (C<( EXPR )>). Example:
+
+ fun foo(('Int') $n, ($othertype) $x) { ... }
+
+Every type expression must return either a string (which is resolved as for
+literal types), or a L<type constraint object|Moose::Meta::TypeConstraint>
+(providing C<check> and C<get_message> methods).
+
+Note that these expressions are evaluated (once) at parse time (similar to
+C<BEGIN> blocks), so make sure that any variables you use are set and any
+functions you call are defined at parse time.
+
=head2 How it works
The module is actually written in L<C|perlxs> and uses
# ... turns into ...
sub bar :method { my $self = shift; my ($x, $y, @z) = @_; sub bar; ... }
+=head1 SUPPORT AND DOCUMENTATION
+
+After installing, you can find documentation for this module with the
+perldoc command.
+
+ perldoc Function::Parameters
+
+You can also look for information at:
+
+=over
+
+=item MetaCPAN
+
+L<https://metacpan.org/module/Function%3A%3AParameters>
+
+=item RT, CPAN's request tracker
+
+L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Function-Parameters>
+
+=item AnnoCPAN, Annotated CPAN documentation
+
+L<http://annocpan.org/dist/Function-Parameters>
+
+=item CPAN Ratings
+
+L<http://cpanratings.perl.org/d/Function-Parameters>
+
+=item Search CPAN
+
+L<http://search.cpan.org/dist/Function-Parameters/>
+
+=back
+
=head1 SEE ALSO
L<Function::Parameters::Info>
=head1 COPYRIGHT & LICENSE
-Copyright 2010, 2011, 2012 Lukas Mai.
+Copyright 2010-2013 Lukas Mai.
This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published