From: Florian Ragwitz Date: Fri, 5 Feb 2010 18:49:08 +0000 (+0100) Subject: Make ScalarRef parameterized. X-Git-Tag: 0.96~2 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=2c29c0e7b6e2fccdbee66b0ddf503123ae748ad0;p=gitmo%2FMoose.git Make ScalarRef parameterized. --- diff --git a/Changes b/Changes index d535c79..e6a3d76 100644 --- a/Changes +++ b/Changes @@ -1,6 +1,11 @@ Also see Moose::Manual::Delta for more details of, and workarounds for, noteworthy changes. + [NEW FEATURES] + * ScalarRef is now a parameterized type. You can now specify a type + constraint for whatever the reference points to. (Closes RT#50857) + (Michael G. Schwern, Florian Ragwitz) + 0.95 Thu, Feb 4, 2010 [NEW FEATURES] diff --git a/lib/Moose/Util/TypeConstraints.pm b/lib/Moose/Util/TypeConstraints.pm index 06733df..88ddf81 100644 --- a/lib/Moose/Util/TypeConstraints.pm +++ b/lib/Moose/Util/TypeConstraints.pm @@ -672,9 +672,6 @@ subtype 'Num' => as 'Str' => subtype 'Int' => as 'Num' => where { "$_" =~ /^-?[0-9]+$/ } => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Int; -subtype 'ScalarRef' => as 'Ref' => where { ref($_) eq 'SCALAR' } => - optimize_as - \&Moose::Util::TypeConstraints::OptimizedConstraints::ScalarRef; subtype 'CodeRef' => as 'Ref' => where { ref($_) eq 'CODE' } => optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::CodeRef; subtype 'RegexpRef' => as 'Ref' => where { ref($_) eq 'Regexp' } => @@ -717,6 +714,24 @@ subtype 'RoleName' => as 'ClassName' => where { $REGISTRY->add_type_constraint( Moose::Meta::TypeConstraint::Parameterizable->new( + name => 'ScalarRef', + package_defined_in => __PACKAGE__, + parent => find_type_constraint('Ref'), + constraint => sub { ref($_) eq 'SCALAR' }, + optimized => + \&Moose::Util::TypeConstraints::OptimizedConstraints::ScalarRef, + constraint_generator => sub { + my $type_parameter = shift; + my $check = $type_parameter->_compiled_type_constraint; + return sub { + return $check->(${ $_ }); + }; + } + ) +); + +$REGISTRY->add_type_constraint( + Moose::Meta::TypeConstraint::Parameterizable->new( name => 'ArrayRef', package_defined_in => __PACKAGE__, parent => find_type_constraint('Ref'), @@ -775,7 +790,7 @@ $REGISTRY->add_type_constraint( ); my @PARAMETERIZABLE_TYPES - = map { $REGISTRY->get_type_constraint($_) } qw[ArrayRef HashRef Maybe]; + = map { $REGISTRY->get_type_constraint($_) } qw[ScalarRef ArrayRef HashRef Maybe]; sub get_all_parameterizable_types {@PARAMETERIZABLE_TYPES} @@ -894,7 +909,7 @@ that hierarchy represented visually. ClassName RoleName Ref - ScalarRef + ScalarRef[`a] ArrayRef[`a] HashRef[`a] CodeRef @@ -908,6 +923,7 @@ parameterized, this means you can say: ArrayRef[Int] # an array of integers HashRef[CodeRef] # a hash of str to CODE ref mappings + ScalarRef[Int] # a reference to an integer Maybe[Str] # value may be a string, may be undefined If Moose finds a name in brackets that it does not recognize as an diff --git a/t/040_type_constraints/016_subtyping_parameterized_types.t b/t/040_type_constraints/016_subtyping_parameterized_types.t index 993c63d..3c6971f 100644 --- a/t/040_type_constraints/016_subtyping_parameterized_types.t +++ b/t/040_type_constraints/016_subtyping_parameterized_types.t @@ -120,4 +120,12 @@ lives_ok { }, qr/Str is not a subtype of BiggerInt/, 'Failed to parameterize with a bad type parameter'; } +{ + my $RefToInt = subtype as 'ScalarRef[Int]'; + + ok $RefToInt->check(\1), '\1 is okay'; + ok !$RefToInt->check(1), '1 is not'; + ok !$RefToInt->check(\"foo"), '\"foo" is not'; +} + done_testing;