X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FFunction%2FParameters.pm;h=8720269a32a1dfa966b63bc7eca481317adf815b;hb=7193dffba45795c249b405f8636d644261380ff0;hp=101a34fa420ef612a865d49137fa883e2245f6f9;hpb=d72d56ce74efe8558da8154d85aea834ff87dfc6;p=p5sagit%2FFunction-Parameters.git diff --git a/lib/Function/Parameters.pm b/lib/Function/Parameters.pm index 101a34f..8720269 100644 --- a/lib/Function/Parameters.pm +++ b/lib/Function/Parameters.pm @@ -52,6 +52,11 @@ sub _assert_valid_attributes { }sx or confess qq{"$attrs" doesn't look like valid attributes}; } +sub _reify_type_default { + require Moose::Util::TypeConstraints; + Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($_[0]) +} + my @bare_arms = qw(function method); my %type_map = ( function => { @@ -60,6 +65,7 @@ my %type_map = ( check_argument_count => 0, named_parameters => 1, types => 1, + reify_type => \&_reify_type_default, }, method => { name => 'optional', @@ -67,6 +73,7 @@ my %type_map = ( check_argument_count => 0, named_parameters => 1, types => 1, + reify_type => \&_reify_type_default, attrs => ':method', shift => '$self', invocant => 1, @@ -77,6 +84,7 @@ my %type_map = ( check_argument_count => 0, named_parameters => 1, types => 1, + reify_type => \&_reify_type_default, attributes => ':method', shift => '$class', invocant => 1, @@ -89,6 +97,8 @@ for my $k (keys %type_map) { }; } +our @type_reifiers = \&_reify_type_default; + sub import { my $class = shift; @@ -143,11 +153,30 @@ sub import { ? !!delete $type{default_arguments} : 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}; + if (my $rt = delete $type{reify_type}) { + ref $rt eq 'CODE' or confess qq{"$rt" doesn't look like a type reifier}; + + my $index; + for my $i (0 .. $#type_reifiers) { + if ($type_reifiers[$i] == $rt) { + $index = $i; + last; + } + } + unless (defined $index) { + $index = @type_reifiers; + push @type_reifiers, $rt; + } + + $clean{reify_type} = $index; + } + %type and confess "Invalid keyword property: @{[keys %type]}"; $spec{$name} = \%clean; @@ -169,6 +198,7 @@ sub import { $^H{HINTK_FLAGS_ . $kw} = $flags; $^H{HINTK_SHIFT_ . $kw} = $type->{shift}; $^H{HINTK_ATTRS_ . $kw} = $type->{attrs}; + $^H{HINTK_REIFY_ . $kw} = $type->{reify_type} // 0; $^H{+HINTK_KEYWORDS} .= "$kw "; } } @@ -615,6 +645,22 @@ automatically check that they have been passed all required arguments and no excess arguments. If this check fails, an exception will by thrown via L|Carp>. +Currently this flag is overloaded to also enable type checks (see +L below). + +=item C + +Valid values: code references. The function specified here will be called to +turn type annotations into constraint objects (see +L below). + +The default type reifier is equivalent to: + + sub { + require Moose::Util::TypeConstraints; + Moose::Util::TypeConstraints::find_or_create_isa_type_constraint($_[0]) + } + =back The predefined type C is equivalent to: @@ -694,15 +740,17 @@ affects the file that is currently being compiled. =head2 Experimental feature: Types An experimental feature is now available: You can annotate parameters with -L. That is, before each parameter you can put -a type specification consisting of identifiers (C), unions (C<... | ...>), -and parametric types (C<...[...]>). Example: +types. That is, before each parameter you can put a type specification +consisting of identifiers (C), unions (C<... | ...>), and parametric types +(C<...[...]>). Example: fun foo(Int $n, ArrayRef[String | CodeRef] $cb) { ... } -If you do this, L will be loaded automatically (if that hasn't happened -yet). These specifications are parsed and validated using -L|Moose::Util::TypeConstraints/find_or_parse_type_constraint>. +If you do this, the type reification function corresponding to the keyword will +be called to turn the type (a string) into a constraint object. The default +type reifier simply loads L and forwards to +L|Moose::Util::TypeConstraints/find_or_parse_type_constraint>, +which creates L. If you are in "lax" mode, nothing further happens and the types are ignored. If you are in "strict" mode, C generates code to make sure