sub type_export_generator {
my ($class, $type, $name) = @_;
+
+ ## Return an anonymous subroutine that will generate the proxied type
+ ## constraint for you.
+
return sub {
my $type_constraint;
if(defined(my $params = shift @_)) {
+ ## We currently only allow a TC to accept a single, ArrayRef
+ ## parameter, as in HashRef[Int], where [Int] is what's inside the
+ ## ArrayRef passed.
if(ref $params eq 'ARRAY') {
$type_constraint = $class->create_arged_type_constraint($name, @$params);
} else {
my $type_decorator = $class->create_type_decorator($type_constraint);
+ ## If there are additional args, that means it's probably stuff that
+ ## needs to be returned to the subtype. Not an ideal solution here but
+ ## doesn't seem to cause trouble.
+
if(@_) {
return ($type_decorator, @_);
} else {
=head2 create_arged_type_constraint ($name, @args)
-Given a String $name with @args find the matching typeconstraint.
+Given a String $name with @args find the matching typeconstraint and parameterize
+it with @args.
=cut
sub create_arged_type_constraint {
my ($class, $name, @args) = @_;
my $type_constraint = Moose::Util::TypeConstraints::find_or_create_type_constraint($name);
- return $type_constraint->parameterize(@args)
+ return $type_constraint->parameterize(@args);
}
=head2 create_base_type_constraint ($name)
=head1 CAVEATS
+The following are lists of gotcha's and their workarounds for developers coming
+from the standard string based type constraint names
+
+=head2 Uniqueness
+
A library makes the types quasi-unique by prefixing their names with (by
default) the library package name. If you're only using the type handler
functions provided by MooseX::Types, you shouldn't ever have to use
a type's actual full name.
+=head2 Argument separation ('=>' versus ',')
+
+The Perlop manpage has this to say about the '=>' operator: "The => operator is
+a synonym for the comma, but forces any word (consisting entirely of word
+characters) to its left to be interpreted as a string (as of 5.001). This
+includes words that might otherwise be considered a constant or function call."
+
+Due to this stringification, the following will NOT work as you might think:
+
+ subtype StrOrArrayRef => as Str|ArrayRef;
+
+The 'StrOrArrayRef' will have it's stringification activated this causes the
+subtype to not be created. Since the bareword type constraints are not strings
+you really should not try to treat them that way. You will have to use the ','
+operator instead. The author's of this package realize that all the L<Moose>
+documention and examples nearly uniformly use the '=>' version of the comma
+operator and this could be an issue if you are converting code.
+
+Patches welcome for discussion.
+
=head1 SEE ALSO
L<Moose>,
use overload(
'""' => sub {
- shift->__type_constraint->name;
+ return shift->__type_constraint->name;
},
'|' => sub {
+
+ ## It's kind of ugly that we need to know about Union Types, but this
+ ## is needed for syntax compatibility. Maybe someday we'll all just do
+ ## Or[Str,Str,Int]
+
my @tc = grep {ref $_} @_;
my $union = Moose::Meta::TypeConstraint::Union->new(type_constraints=>\@tc);
return Moose::Util::TypeConstraints::register_type_constraint($union);
croak "Argument must be ->isa('Moose::Meta::TypeConstraint') or ->isa('MooseX::Types::UndefinedType')";
}
} else {
- croak "This method [new] requires a single argument";
+ croak "This method [new] requires a single argument of 'arg'.";
}
}
-=head type_constraint ($type_constraint)
+=head __type_constraint ($type_constraint)
Set/Get the type_constraint.
=cut
sub isa {
- my ($self, $target) = @_;
+ my ($self, $target) = @_;
if(defined $target) {
return $self->__type_constraint->isa($target);
} else {
use warnings;
use strict;
-use Test::More tests => 47;
+use Test::More tests => 49;
use Test::Exception;
use FindBin;
use lib "$FindBin::Bin/lib";
);
use DecoratorLibrary qw(
MyArrayRefBase MyArrayRefInt01 MyArrayRefInt02 StrOrArrayRef
- AtLeastOneInt
+ AtLeastOneInt Jobs
);
has 'arrayrefbase' => (is=>'rw', isa=>MyArrayRefBase, coerce=>1);
has 'pipeoverloading' => (is=>'rw', isa=>Int|Str);
has 'deep' => (is=>'rw', isa=>ArrayRef[ArrayRef[HashRef[Int]]] );
has 'deep2' => (is=>'rw', isa=>ArrayRef[Int|ArrayRef[HashRef[Int|Object]]] );
+ has 'enum' => (is=>'rw', isa=>Jobs);
}
## Make sure we have a 'create object sanity check'
is_deeply $type->deep2, [1,2,3],
=> 'Assignment is correct';
+
+## Test jobs
+
+ok $type->enum('Programming')
+ => 'Good Assignment of Programming to Enum';
+
+
+throws_ok sub {
+ $type->enum('ddddd');
+}, qr/Attribute \(enum\) does not pass the type constraint/ => 'Enum properly fails';