* 00000000 00000000 00000000 00000000
* ^ trigger
* ^ weak
- * ^ tc refcnt
+ * ^ tc.sv is refcounted
* ^^^ tc_kind
* ^ coerce
* ^^^ default_kind
* ^ lazy
+ * ^ def.sv is refcounted
* ^ required
* ^^^^^^^ if 0 then nothing special (just hash)? FIXME TBD
*/
return 0;
}
+STATIC bool check_sv_cv (pTHX_ SV *cv, SV *sv) {
+ bool ret;
+ dSP;
+
+ ENTER;
+ SAVETMPS;
+ PUSHMARK(SP);
+ XPUSHs(sv);
+ PUTBACK;
+
+ call_sv(cv, G_SCALAR);
+
+ SPAGAIN;
+ ret = SvTRUE(POPs);
+
+ PUTBACK;
+ FREETMPS;
+ LEAVE;
+
+ return ret;
+}
+
STATIC bool check_type_constraint(pTHX_ tc_kind kind, TC_CHECK tc_check, SV *type_constraint, SV *sv) {
switch (kind) {
case tc_none:
return tc_check.fptr(aTHX_ type_constraint, sv);
break;
case tc_cv:
+ return check_sv_cv(aTHX_ tc_check.sv, sv);
+ break;
case tc_op:
croak("todo");
break;
return ( undef, 0, undef ) unless $tc;
- if ( ref $tc eq 'Moose::Meta::TypeConstraint' or ref $tc eq 'Moose::Meta::TypeConstraint::Parameterizable') {
+ if (
+ # sleazy check for core types that haven't been parametrized
+ #(ref $tc eq 'Moose::Meta::TypeConstraint' or ref $tc eq 'Moose::Meta::TypeConstraint::Parameterizable')
+ # and
+ exists $checks{$tc->name}
+ ) {
# builtin moose type #
return ( $tc, 1, $checks{$tc->name} );
} elsif ( $tc->isa("Moose::Meta::TypeConstraint::Class") ) {
return ( $tc, 2, $tc->class );
} else {
- warn ref $tc;
return ( $tc, 3, $tc->_compiled_type_constraint );
}
}
package Foo;
use Moose;
+ use Moose::Util::TypeConstraints;
+
+ subtype( 'FiveChars',
+ as "Str",
+ where { length == 5 },
+ );
+
has x => ( is => "rw", predicate => "has_x" );
has y => ( is => "ro" );
has z => ( reader => "z", setter => "set_z" );
has f => ( isa => "Foo", is => "rw" );
has c => ( isa => "ClassName", is => "rw" );
has b => ( is => "ro", lazy_build => 1 ); # fixme type constraint checking
+ has tc => ( is => "rw", isa => "FiveChars" );
sub _build_b { "builded!" }
ok( !eval { $foo->c(undef); 1 }, "ClassName" );
ok( !eval { $foo->c("feck"); 1 }, "ClassName" );
ok( !eval { $foo->c({}); 1 }, "ClassName" );
+ok( !eval { $foo->tc(undef); 1 }, "custom type" );
+ok( !eval { $foo->tc(""); 1 }, "custom type" );
+ok( !eval { $foo->tc("foo"); 1 }, "custom type" );
+ok( !eval { $foo->tc(3); 1 }, "custom type" );
+ok( !eval { $foo->tc([]); 1 }, "custom type" );
ok( eval { $foo->a([]); 1 }, "ArrayRef" );
ok( eval { $foo->i(3); 1 }, "Int" );
ok( eval { $foo->f(Gorch->new); 1 }, "Class (Foo), real subclass");
ok( eval { $foo->f(Quxx->new); 1 }, "Class (Foo), fake subclass");
ok( eval { $foo->c("Foo"); 1 }, "ClassName" );
+ok( eval { $foo->tc("hello"); 1 }, "custom type" );
isa_ok( $foo->f, 'Foo' );
$foo->meta->invalidate_meta_instance();
isa_ok( $foo->f, 'Foo' );
+