1 package Moose::Meta::TypeConstraint::Class;
8 use Scalar::Util 'blessed';
9 use Moose::Util::TypeConstraints ();
11 use base 'Moose::Meta::TypeConstraint';
13 __PACKAGE__->meta->add_attribute('class' => (
15 Class::MOP::_definition_context(),
22 return 'Scalar::Util::blessed(' . $val . ')'
23 . ' && ' . $val . '->isa(' . B::perlstring($self->class) . ')';
27 my ( $class, %args ) = @_;
30 = Moose::Util::TypeConstraints::find_type_constraint('Object');
32 my $class_name = $args{class};
33 $args{constraint} = sub { $_[0]->isa($class_name) };
35 $args{inlined} = $inliner;
37 my $self = $class->SUPER::new( \%args );
39 $self->compile_type_constraint();
49 # FIXME find_type_constraint might find a TC named after the class but that isn't really it
50 # I did this anyway since it's a convention that preceded TypeConstraint::Class, and it should DWIM
51 # if anybody thinks this problematic please discuss on IRC.
52 # a possible fix is to add by attr indexing to the type registry to find types of a certain property
53 # regardless of their name
54 Moose::Util::TypeConstraints::find_type_constraint($_)
56 __PACKAGE__->new( class => $_, name => "__ANON__" )
57 } Class::MOP::class_of($self->class)->superclasses,
62 my ( $self, $type_or_name ) = @_;
64 my $other = Moose::Util::TypeConstraints::find_type_constraint($type_or_name);
66 if (!defined($other)) {
67 if (!ref($type_or_name)) {
68 return $self->class eq $type_or_name;
73 return unless $other->isa(__PACKAGE__);
75 return $self->class eq $other->class;
79 my ($self, $type_or_name) = @_;
81 ($self->equals($type_or_name) || $self->is_subtype_of($type_or_name));
85 my ($self, $type_or_name_or_class ) = @_;
87 my $type = Moose::Util::TypeConstraints::find_type_constraint($type_or_name_or_class);
89 if ( not defined $type ) {
90 if ( not ref $type_or_name_or_class ) {
92 my $class = $self->class;
93 return 1 if $class ne $type_or_name_or_class
94 && $class->isa( $type_or_name_or_class );
99 if ( $type->isa(__PACKAGE__) && $type->class ne $self->class) {
100 # if $type_or_name_or_class isn't a class, it might be the TC name of another ::Class type
101 # or it could also just be a type object in this branch
102 return $self->class->isa( $type->class );
104 # the only other thing we are a subtype of is Object
105 $self->SUPER::is_subtype_of($type);
109 # This is a bit counter-intuitive, but a child type of a Class type
110 # constraint is not itself a Class type constraint (it has no class
111 # attribute). This whole create_child_type thing needs some changing
112 # though, probably making MMC->new a factory or something.
113 sub create_child_type {
114 my ($self, @args) = @_;
115 return Moose::Meta::TypeConstraint->new(@args, parent => $self);
122 if ($self->has_message) {
123 return $self->SUPER::get_message(@_);
126 $value = (defined $value ? overload::StrVal($value) : 'undef');
127 return "Validation failed for '" . $self->name . "' with value $value (not isa " . $self->class . ")";
132 # ABSTRACT: Class/TypeConstraint parallel hierarchy
140 This class represents type constraints for a class.
144 C<Moose::Meta::TypeConstraint::Class> is a subclass of
145 L<Moose::Meta::TypeConstraint>.
151 =item B<< Moose::Meta::TypeConstraint::Class->new(%options) >>
153 This creates a new class type constraint based on the given
156 It takes the same options as its parent, with two exceptions. First,
157 it requires an additional option, C<class>, which is name of the
158 constraint's class. Second, it automatically sets the parent to the
161 The constructor also overrides the hand optimized type constraint with
162 one it creates internally.
164 =item B<< $constraint->class >>
166 Returns the class name associated with the constraint.
168 =item B<< $constraint->parents >>
170 Returns all the type's parent types, corresponding to its parent
173 =item B<< $constraint->is_subtype_of($type_name_or_object) >>
175 If the given type is also a class type, then this checks that the
176 type's class is a subclass of the other type's class.
178 Otherwise it falls back to the implementation in
179 L<Moose::Meta::TypeConstraint>.
181 =item B<< $constraint->create_child_type(%options) >>
183 This returns a new L<Moose::Meta::TypeConstraint> object with the type
186 Note that it does I<not> return a
187 C<Moose::Meta::TypeConstraint::Class> object!
189 =item B<< $constraint->get_message($value) >>
191 This is the same as L<Moose::Meta::TypeConstraint/get_message> except
192 that it explicitly says C<isa> was checked. This is to help users deal
193 with accidentally autovivified type constraints.
199 See L<Moose/BUGS> for details on reporting bugs.