Skip Menu |

This queue is for tickets about the Type-Tiny CPAN distribution.

Report information
The Basics
Id: 87264
Status: resolved
Priority: 0/
Queue: Type-Tiny

People
Owner: perl [...] toby.ink
Requestors: TIMB [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Unimportant
Broken in: (no value)
Fixed in: (no value)



Subject: I was bitten by equals() being looser than expected (ie structural) which impacts is_subtype_of()
use Type::Library -base, -declare => qw(T1 T2); use Types::Standard qw(Int); use Type::Utils -all; declare T1, as Int; declare T2, as Int; die "Oops!" if T1->is_subtype_of(T2); Here T1 is clearly not a subtype of T2 yet Type::Tiny says it is: T1->is_subtype_of(T2); returns true! Looking at the source, and the source of Moose::Meta::TypeConstraint, it seems that Type::Tiny and Moose implement equals() to mean something like "equivalent constraints". This isn't made clear in the docs of either. I'd argue that is_subtype_of should use a stricter check but I've no idea what the backwards compatibility issues might be. This is a problem when trying to use types for more than just constraint checking.
The current is_subtype_of acts similarly to Moose's. (There are differences in implementation, but in my opinion they're similar in spirit.) So I don't want to significantly change it's behaviour, but I'm happy to add stricter versions of the methods.
A doc patch pointing out that equals() is really an "equivalent constraints" check and the effect that has on is_subtype_of() would suffice for me. I ended up changing the code to effectively grep the results of parents(), so that might be worth pointing out in the docs as an alternative. (Also a vote in favor of your parents() behaviour.)
I've changed the documentation to: "equals($other)", "is_subtype_of($other)", "is_supertype_of($other)", "is_a_type_of($other)" Compare two types. See Moose::Meta::TypeConstraint for what these all mean. (OK, Moose doesn't define "is_supertype_of", but you get the idea, right?) Note that these have a slightly DWIM side to them. If you create two Type::Tiny::Class objects which test the same class, they're considered equal. And: my $subtype_of_Num = Types::Standard::Num->create_child_type; my $subtype_of_Int = Types::Standard::Int->create_child_type; $subtype_of_Int->is_subtype_of( $subtype_of_Num ); # true
And added the following methods: "strictly_equals($other)", "is_strictly_subtype_of($other)", "is_strictly_supertype_of($other)", "is_strictly_a_type_of($other)" Stricter versions of the type comparison functions. These only care about explicit inheritance via "parent". my $subtype_of_Num = Types::Standard::Num->create_child_type; my $subtype_of_Int = Types::Standard::Int->create_child_type; $subtype_of_Int->is_strictly_subtype_of( $subtype_of_Num ); # false
0.021_01 includes the above changes.
Show quoted text
> Note that these have a slightly DWIM side to them.
I think it's worth clarifying that. Perhaps by talking in terms of "checking for equivalent constraints". Also the example could be made simpler: my $subtype1 = Types::Standard::Int->create_child_type; my $subtype2 = Types::Standard::Int->create_child_type; $subtype1->is_subtype_of( $subtype2 ); # true To my mind that makes the issue stand out more clearly.
Resolved in 0.022.