bool => sub { 1 },
fallback => 1;
+use Carp qw(confess);
+use Class::Load qw(load_class);
use Eval::Closure;
use Scalar::Util qw(blessed refaddr);
use Sub::Name qw(subname);
use base qw(Class::MOP::Object);
-__PACKAGE__->meta->add_attribute('name' => (reader => 'name'));
+__PACKAGE__->meta->add_attribute('name' => (
+ reader => 'name',
+ Class::MOP::_definition_context(),
+));
__PACKAGE__->meta->add_attribute('parent' => (
reader => 'parent',
predicate => 'has_parent',
+ Class::MOP::_definition_context(),
));
my $null_constraint = sub { 1 };
__PACKAGE__->meta->add_attribute('constraint' => (
reader => 'constraint',
writer => '_set_constraint',
- default => sub { $null_constraint }
+ default => sub { $null_constraint },
+ Class::MOP::_definition_context(),
));
+
__PACKAGE__->meta->add_attribute('message' => (
accessor => 'message',
- predicate => 'has_message'
+ predicate => 'has_message',
+ Class::MOP::_definition_context(),
));
+
+__PACKAGE__->meta->add_attribute('_default_message' => (
+ accessor => '_default_message',
+ Class::MOP::_definition_context(),
+));
+
+# can't make this a default because it has to close over the type name, and
+# cmop attributes don't have lazy
+my $_default_message_generator = sub {
+ my $name = shift;
+ sub {
+ my $value = shift;
+ # have to load it late like this, since it uses Moose itself
+ my $can_partialdump = try {
+ # versions prior to 0.14 had a potential infinite loop bug
+ load_class('Devel::PartialDump', { -version => 0.14 });
+ 1;
+ };
+ if ($can_partialdump) {
+ $value = Devel::PartialDump->new->dump($value);
+ }
+ else {
+ $value = (defined $value ? overload::StrVal($value) : 'undef');
+ }
+ return "Validation failed for '" . $name . "' with value $value";
+ }
+};
__PACKAGE__->meta->add_attribute('coercion' => (
accessor => 'coercion',
- predicate => 'has_coercion'
+ predicate => 'has_coercion',
+ Class::MOP::_definition_context(),
));
__PACKAGE__->meta->add_attribute('hand_optimized_type_constraint' => (
init_arg => 'optimized',
accessor => 'hand_optimized_type_constraint',
predicate => 'has_hand_optimized_type_constraint',
+ Class::MOP::_definition_context(),
));
__PACKAGE__->meta->add_attribute('inlined' => (
init_arg => 'inlined',
accessor => 'inlined',
predicate => '_has_inlined_type_constraint',
+ Class::MOP::_definition_context(),
));
__PACKAGE__->meta->add_attribute('inline_environment' => (
init_arg => 'inline_environment',
accessor => '_inline_environment',
default => sub { {} },
+ Class::MOP::_definition_context(),
));
sub parents {
__PACKAGE__->meta->add_attribute('compiled_type_constraint' => (
accessor => '_compiled_type_constraint',
- predicate => '_has_compiled_type_constraint'
+ predicate => '_has_compiled_type_constraint',
+ Class::MOP::_definition_context(),
));
+
__PACKAGE__->meta->add_attribute('package_defined_in' => (
- accessor => '_package_defined_in'
+ accessor => '_package_defined_in',
+ Class::MOP::_definition_context(),
));
sub new {
my %args = ref $first ? %$first : $first ? ($first, @rest) : ();
$args{name} = $args{name} ? "$args{name}" : "__ANON__";
+ if ( $args{optimized} ) {
+ Moose::Deprecated::deprecated(
+ feature => 'optimized type constraint sub ref',
+ message =>
+ 'Providing an optimized subroutine ref for type constraints is deprecated.'
+ . ' Use the inlining feature (inline_as) instead.'
+ );
+ }
+
+ if ( exists $args{message}
+ && (!ref($args{message}) || ref($args{message}) ne 'CODE') ) {
+ confess("The 'message' parameter must be a coderef");
+ }
+
my $self = $class->_new(%args);
$self->compile_type_constraint()
unless $self->_has_compiled_type_constraint;
+ $self->_default_message($_default_message_generator->($self->name))
+ unless $self->has_message;
return $self;
}
sub get_message {
my ($self, $value) = @_;
- if (my $msg = $self->message) {
- local $_ = $value;
- return $msg->($value);
- }
- else {
- # have to load it late like this, since it uses Moose itself
- my $can_partialdump = try {
- # versions prior to 0.14 had a potential infinite loop bug
- Class::MOP::load_class('Devel::PartialDump', { -version => 0.14 });
- 1;
- };
- if ($can_partialdump) {
- $value = Devel::PartialDump->new->dump($value);
- }
- else {
- $value = (defined $value ? overload::StrVal($value) : 'undef');
- }
- return "Validation failed for '" . $self->name . "' with value $value";
- }
+ my $msg = $self->has_message
+ ? $self->message
+ : $self->_default_message;
+ local $_ = $value;
+ return $msg->($value);
}
## type predicates ...
my $current = $self;
while (my $parent = $current->parent) {
- return 1 if $parent->equals($type);
+ return 1 if $parent->is_a_type_of($type);
$current = $parent;
}