Subject: | [PATCH] Compatibility with constants and with CV-in-stash optimisation |
See the attached patch. The test I added fails in perl 5.12.4 (the only one I tested it with), because Type::Tiny assumes that all stash elements are typeglobs. This assumption has not been true since perl 5.005 or so.
This patch gets things working, but there is still a discrepancy in behaviour if someone declares a sub like this:
sub foo($);
and puts nothing else in the package, in which case the ClassName constraint will fail, until someone takes a reference to \&foo, and then it will pass, since undefined stubs are by default stored as simple scalars. If you want undefined subroutines to make a package into a class as far as Type::Tiny is concerned, then the ‘ref $globref’ in the patch should be ‘defined $globref’. If you want only defined subroutines to make a package a class, then let me know and I can write a patch.
If you want to keep things as close to the current, slightly inconsistent, behaviour as possible, but without croaking on some stash elements, then use this patch as it is.
I encountered this problem because of the CV-in-stash optimisation (described at <https://rt.perl.org/Ticket/Display.html?id=132252#txn-1500037>), which causes Type::Tiny to fails its tests as long as the recommended prerequisites are not installed.
I hope that this issue can be resolved soon, so that the perl optimisation, which was temporarily reverted, can be restored before perl 5.28.
Thank you.
Subject: | open_vTWSAbr3.txt |
diff -rup Type-Tiny-1.002001-0/lib/Types/Standard.pm Type-Tiny-1.002001-ZnsxIn/lib/Types/Standard.pm
--- Type-Tiny-1.002001-0/lib/Types/Standard.pm 2017-06-08 04:55:23.000000000 -0700
+++ Type-Tiny-1.002001-ZnsxIn/lib/Types/Standard.pm 2017-10-27 10:36:28.000000000 -0700
@@ -33,7 +33,10 @@ BEGIN {
return !!1 if exists $stash->{'ISA'};
return !!1 if exists $stash->{'VERSION'};
foreach my $globref (values %$stash) {
- return !!1 if *{$globref}{CODE};
+ return !!1
+ if ref \$globref eq 'GLOB'
+ ? *{$globref}{CODE}
+ : ref $globref; # const or sub ref
}
return !!0;
};
diff -rup Type-Tiny-1.002001-0/t/20-unit/Type-Tiny/arithmetic.t Type-Tiny-1.002001-ZnsxIn/t/20-unit/Type-Tiny/arithmetic.t
--- Type-Tiny-1.002001-0/t/20-unit/Type-Tiny/arithmetic.t 2017-06-08 04:55:23.000000000 -0700
+++ Type-Tiny-1.002001-ZnsxIn/t/20-unit/Type-Tiny/arithmetic.t 2017-10-27 10:46:34.000000000 -0700
@@ -85,11 +85,13 @@ should_pass(undef, ~Value);
{
package Local::Class4;
sub XYZ () { 1 }
+ package Local::Class5;
+ use constant XZY => 2
}
should_pass(undef, ~ClassName);
should_pass([], ~ClassName);
-should_fail("Local::Class$_", ~ClassName) for 2..4;
+should_fail("Local::Class$_", ~ClassName) for 2..5;
should_pass("Local::Dummy1", ~ClassName);
should_fail([], ~(ArrayRef[Int]));