{{$NEXT}}
+ [API CHANGES]
+
+ * The RegexpRef type constraint now accepts regular expressions blessed into
+ other classes, such as those found in pluggable regexp engines.
+ Additionally the 'Object' constraint no longer rejects objects which
+ implementation is a regular expression. (David Leadbeater)
+
1.9906-TRIAL Mon, Apr 04, 2011
[OTHER]
my $class = $self->class;
$self->hand_optimized_type_constraint(
sub {
- blessed( $_[0] ) && blessed( $_[0] ) ne 'Regexp' && $_[0]->isa($class)
+ blessed( $_[0] ) && $_[0]->isa($class)
}
);
}
subtype 'CodeRef' => as 'Ref' => where { ref($_) eq 'CODE' } =>
optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::CodeRef;
-subtype 'RegexpRef' => as 'Ref' => where { ref($_) eq 'Regexp' } =>
- optimize_as
- \&Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef;
+subtype 'RegexpRef' => as 'Ref' =>
+ where(\&Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef) =>
+ optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef;
subtype 'GlobRef' => as 'Ref' => where { ref($_) eq 'GLOB' } =>
optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::GlobRef;
} => optimize_as
\&Moose::Util::TypeConstraints::OptimizedConstraints::FileHandle;
-# NOTE:
-# blessed(qr/.../) returns true,.. how odd
subtype 'Object' => as 'Ref' =>
- where { blessed($_) && blessed($_) ne 'Regexp' } =>
+ where { blessed($_) } =>
optimize_as \&Moose::Util::TypeConstraints::OptimizedConstraints::Object;
# This type is deprecated.
sub ArrayRef { ref($_[0]) eq 'ARRAY' }
sub HashRef { ref($_[0]) eq 'HASH' }
sub CodeRef { ref($_[0]) eq 'CODE' }
-sub RegexpRef { ref($_[0]) eq 'Regexp' }
sub GlobRef { ref($_[0]) eq 'GLOB' }
+# RegexpRef is implemented in Moose.xs
+
sub FileHandle { ref($_[0]) eq 'GLOB' && Scalar::Util::openhandle($_[0]) or blessed($_[0]) && $_[0]->isa("IO::Handle") }
-sub Object { blessed($_[0]) && blessed($_[0]) ne 'Regexp' }
+sub Object { blessed($_[0]) }
sub Role {
Moose::Deprecated::deprecated(
ok( !$type->equals(Moose::Meta::TypeConstraint::Class->new( name => "__ANON__", class => "Bar" )), "doesn't equal other anon constraint" );
ok( $type->is_subtype_of(Moose::Meta::TypeConstraint::Class->new( name => "__ANON__", class => "Bar" )), "subtype of other anon constraint" );
-{
- my $regexp_type = Moose::Meta::TypeConstraint::Class->new(name => 'Regexp', class => 'Regexp');
- ok(!$regexp_type->check(qr//), 'a Regexp is not an instance of a class, even tho perl pretends it is');
-}
-
done_testing;
ok(!defined RegexpRef($GLOB_REF), '... RegexpRef rejects anything which is not a RegexpRef');
ok(!defined RegexpRef($fh), '... RegexpRef rejects anything which is not a RegexpRef');
ok(defined RegexpRef(qr/../), '... RegexpRef accepts anything which is a RegexpRef');
+ok(defined RegexpRef(bless qr/../, 'Foo'), '... RegexpRef accepts anything which is a RegexpRef');
ok(!defined RegexpRef(bless {}, 'Foo'), '... RegexpRef rejects anything which is not a RegexpRef');
+ok(!defined RegexpRef(bless {}, 'Regexp'), '... RegexpRef rejects anything which is not a RegexpRef');
ok(!defined RegexpRef(undef), '... RegexpRef rejects anything which is not a RegexpRef');
ok(!defined GlobRef(0), '... GlobRef rejects anything which is not a GlobRef');
ok(!defined Object($GLOB), '... Object rejects anything which is not blessed');
ok(!defined Object($GLOB_REF), '... Object rejects anything which is not blessed');
ok(!defined Object($fh), '... Object rejects anything which is not blessed');
-ok(!defined Object(qr/../), '... Object rejects anything which is not blessed');
+ok(defined Object(qr/../), '... Object accepts anything which is blessed');
ok(defined Object(bless {}, 'Foo'), '... Object accepts anything which is blessed');
ok(!defined Object(undef), '... Object accepts anything which is blessed');
ok(!defined RoleName('Moose::Meta::TypeConstraint'), '... RoleName accepts anything which is a RoleName');
ok(defined RoleName('Quux::Wibble::Role'), '... RoleName accepts anything which is a RoleName');
+# Test $_ is read in XS implementation
+{
+ local $_ = qr//;
+ ok(Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef(), '$_ is RegexpRef');
+ ok(!Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef(1), '$_ is not read when param provided');
+ $_ = bless qr//, "blessed";
+ ok(Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef(), '$_ is RegexpRef');
+ $_ = 42;
+ ok(!Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef(), '$_ is not RegexpRef');
+ ok(Moose::Util::TypeConstraints::OptimizedConstraints::RegexpRef(qr//), '$_ is not read when param provided');
+}
+
close($fh) || die "Could not close the filehandle $0 for test";
done_testing;
return 0;
}
+#ifndef SvRXOK
+/* SvRXOK appeared before SVt_REGEXP did, so this implementation assumes magic
+ * based qr//. Note re::is_regexp isn't in 5.8, hence the need for this XS.
+ */
+#define SvRXOK(sv) is_regexp(aTHX_ sv)
+
+STATIC int
+is_regexp (pTHX_ SV* sv) {
+ SV* tmpsv;
+
+ if (SvMAGICAL(sv))
+ mg_get(sv);
+ if (SvROK(sv) &&
+ (tmpsv = (SV*) SvRV(sv)) &&
+ SvTYPE(tmpsv) == SVt_PVMG &&
+ (mg_find(tmpsv, PERL_MAGIC_qr)))
+ return TRUE;
+ return FALSE;
+}
+#endif
+
EXTERN_C XS(boot_Class__MOP);
EXTERN_C XS(boot_Class__MOP__Mixin__HasAttributes);
EXTERN_C XS(boot_Class__MOP__Mixin__HasMethods);
RETVAL = export_flag_is_set(aTHX_ sv);
OUTPUT:
RETVAL
+
+MODULE = Moose PACKAGE = Moose::Util::TypeConstraints::OptimizedConstraints
+
+bool
+RegexpRef (SV *sv=NULL)
+ INIT:
+ if (!items)
+ sv = DEFSV;
+ CODE:
+ RETVAL = SvRXOK(sv);
+ OUTPUT:
+ RETVAL