#find_type_constraint("ClassName")->check($class)
# || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
- my $pkg_defined_in = scalar( caller(1) );
+ my $pkg_defined_in = $options->{package_defined_in} || scalar( caller(1) );
if (my $type = $REGISTRY->get_type_constraint($class)) {
- _confess(
- "The type constraint '$class' has already been created in "
- . $type->_package_defined_in
- . " and cannot be created again in "
- . $pkg_defined_in )
+ if (!($type->isa('Moose::Meta::TypeConstraint::Class') && $type->class eq $class)) {
+ _confess(
+ "The type constraint '$class' has already been created in "
+ . $type->_package_defined_in
+ . " and cannot be created again in "
+ . $pkg_defined_in )
+ }
+ else {
+ return $type;
+ }
}
my %options = (
#find_type_constraint("ClassName")->check($class)
# || __PACKAGE__->_throw_error("Can't create a class type constraint because '$class' is not a class name");
- my $pkg_defined_in = scalar( caller(1) );
+ my $pkg_defined_in = $options->{package_defined_in} || scalar( caller(1) );
if (my $type = $REGISTRY->get_type_constraint($role)) {
- _confess(
- "The type constraint '$role' has already been created in "
- . $type->_package_defined_in
- . " and cannot be created again in "
- . $pkg_defined_in )
+ if (!($type->isa('Moose::Meta::TypeConstraint::Role') && $type->role eq $role)) {
+ _confess(
+ "The type constraint '$role' has already been created in "
+ . $type->_package_defined_in
+ . " and cannot be created again in "
+ . $pkg_defined_in )
+ }
+ else {
+ return $type;
+ }
}
my %options = (
}
sub find_or_create_isa_type_constraint {
- my $type_constraint_name = shift;
+ my ($type_constraint_name, $options) = @_;
find_or_parse_type_constraint($type_constraint_name)
- || create_class_type_constraint($type_constraint_name);
+ || create_class_type_constraint($type_constraint_name, $options);
}
sub find_or_create_does_type_constraint {
- my $type_constraint_name = shift;
+ my ($type_constraint_name, $options) = @_;
find_or_parse_type_constraint($type_constraint_name)
- || create_role_type_constraint($type_constraint_name);
+ || create_role_type_constraint($type_constraint_name, $options);
}
sub find_or_parse_type_constraint {
that hierarchy represented visually.
Any
- Item
- Bool
- Maybe[`a]
- Undef
- Defined
- Value
- Str
- Num
- Int
- ClassName
- RoleName
- Ref
- ScalarRef[`a]
- ArrayRef[`a]
- HashRef[`a]
- CodeRef
- RegexpRef
- GlobRef
- FileHandle
- Object
+ Item
+ Bool
+ Maybe[`a]
+ Undef
+ Defined
+ Value
+ Str
+ Num
+ Int
+ ClassName
+ RoleName
+ Ref
+ ScalarRef[`a]
+ ArrayRef[`a]
+ HashRef[`a]
+ CodeRef
+ RegexpRef
+ GlobRef
+ FileHandle
+ Object
B<NOTE:> Any type followed by a type parameter C<[`a]> can be
parameterized, this means you can say:
assume that the check will be wrapped in parentheses when it is inlined.
The inlined code should include any checks that your type's parent types
-do. For example, the C<Value> type's inlining sub looks like this:
-
- sub {
- 'defined(' . $_[1] . ')'
- . ' && !ref(' . $_[1] . ')'
- }
-
-Note that it checks if the variable is defined, since it is a subtype of
-the C<Defined> type. However, to avoid repeating code, this can be optimized as:
+do. If your parent type constraint defines its own inlining, you can simply use
+that to avoid repeating code. For example, here is the inlining code for the
+C<Value> type, which is a subtype of C<Defined>:
sub {
$_[0]->parent()->_inline_check($_[1])