Skip Menu |

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

Report information
The Basics
Id: 91802
Status: rejected
Priority: 0/
Queue: Type-Tiny

People
Owner: perl [...] toby.ink
Requestors: bpj [...] melroch.se
Cc:
AdminCc:

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



Subject: Types::Standard: please add $class->DOES(...), $class->isa(...) and $class =~ /$valid_class_re/ constraints.
Date: Thu, 02 Jan 2014 20:49:19 +0100
To: bug-Type-Tiny [...] rt.cpan.org
From: BPJ <bpj [...] melroch.se>
Hi, I'm trying to cook up parameterized constraints similar to InstanceOf and ConsumerOf but accepting class names rather than objects as values. I have managed to define them like this, using the high-level stuff from Type::Utils for my $belongs_with ( qw[ isa DOES ] ) { my $name = "Class\u\L$belongs_with"; declare $name, as ClassName, constraint_generator => sub { return ClassName unless @_; croak "Param(s) to $name must be valid class name(s)" if grep { !/$valid_class_re/ } @_; my @classics = my @classes = @_; for my $this ( @classics ) { my $class = $this; $this = declare as Any, where { $_->$belongs_with($class) }, display_name => "$name\['$class']"; } my $classic = @classics > 1 ? union( \@classics ) : $classics[0]; local $" = q[', ']; return intersection [ClassName, $classic], display_name => "$name\['@classes']"; }; } though I'm sure there are not-so-edgy cases where this wouldn't suffice. There is some complication in the declaration since I thought it may be a good idea to not have to check against ClassName more than once, or does ClassName get checked against automatically because of being the parent? (BTW it seems the display_name on the last line never kicks in?) However I think this may be a common enough need to warrant making them standard. The same goes for the following, which is trivial but oft-needed (at least by me) and the regex is a bit clunky to write. my $valid_class_re = qr{ ^ [[:alpha:]] [[:word:]]* (?: :: [[:word:]]+ )* $ }x; # No /ms ! declare 'ValidClassName' => as StrMatch[$valid_class_re]; Cheers, /bpj
From: tobyink [...] cpan.org
OK, a few things... Show quoted text
> though I'm sure there are not-so-edgy cases where > this wouldn't suffice.
It looks like it would work, but is probably more complex than it needs to be. The constraint_generator should normally just return a coderef that's used to further constrain the parent type. It may alternatively return a full Type::Tiny object, but in this case I think a coderef seems simpler: for my $belongs_with ( qw[ isa DOES ] ) { my $name = "Class\u\L$belongs_with"; declare $name, as ClassName, constraint_generator => sub { return ClassName unless @_; croak "Param(s) to $name must be valid class name(s)" if grep { !/$valid_class_re/ } @_; my @classes = @_; return sub { for my $class (@classes) { return 1 if $_->$belongs_with($class); } return; }; }; } Though perhaps your way of building a union and then an intersection may result in nicer error messages when a type check fails. Show quoted text
> There is some complication in the declaration since I > thought it may be a good idea to not have to check against > ClassName more than once, or does ClassName get checked against > automatically because of being the parent?
Actually with parameterized types, Foo is not automatically the parent type of Foo[x]. If the constraint generator returns a coderef, then it will be. But if the constraint generator returns a Type::Tiny object, then the parameterization process simply respects whatever parent that Type::Tiny object already has (if any). Show quoted text
> (BTW it seems the display_name on the last line never > kicks in?)
The intersection function can be called as either: intersection $name, \@constraints; intersection \@constraints; There's no way to pass any additional options. There probably should be. Most of the functions in Type::Utils are blindly borrowed from Moose though, and Moose doesn't. Show quoted text
> However I think this may be a common enough need > to warrant making them standard.
I'm reluctant to add much more to Types::Standard itself, simply because if people import stuff like: use Types::Standard qw(:all); ... then they're already importing an awful lot of functions. I have however recently added Types::Common::Numeric and Types::Common::String to the distribution, and wouldn't necessarily object to adding other such modules along the same lines, provided they had decent test suites, and didn't add any extra dependencies to the distribution. Regarding a "ValidClassName" type constraint, you may be interested in Types::LoadableClass, which has a "ModuleName" constraint.
Subject: Re: [rt.cpan.org #91802] Types::Standard: please add $class->DOES(...), $class->isa(...) and $class =~ /$valid_class_re/ constraints.
Date: Sat, 11 Jan 2014 13:44:57 +0100
To: bug-Type-Tiny [...] rt.cpan.org
From: BPJ <bpj [...] melroch.se>
Excuse me for top posting; I'm writing this on my tanker and sending it thru the gmail app. Yes the gymnastics with unions and intersections was supposed to yield more useful error messages but didn't work out the way I intended. I'm a sucker for informative error messages which often makes me complicate too much. I had hoped the user would get what amounted to a list of permitted superclasses/roles but decided it was better to try to generate a custom message. It was of course slow as well. I quite understand that you don't want to throw everything into a single module. If you think these constraints would really be more generally useful for others I certainly can try to rewrite them without the Type::Utils sugar and write some tests and put it in a module. I'd have to think/look around what other constraints would be useful in relation to classes. Den 10 jan 2014 12:24 skrev "tobyink@cpan.org via RT" < bug-Type-Tiny@rt.cpan.org>: Show quoted text
> <URL: https://rt.cpan.org/Ticket/Display.html?id=91802 > > > OK, a few things... >
> > though I'm sure there are not-so-edgy cases where > > this wouldn't suffice.
> > It looks like it would work, but is probably more complex than it needs to > be. The constraint_generator should normally just return a coderef that's > used to further constrain the parent type. It may alternatively return a > full Type::Tiny object, but in this case I think a coderef seems simpler: > > for my $belongs_with ( qw[ isa DOES ] ) { > my $name = "Class\u\L$belongs_with"; > declare $name, as ClassName, constraint_generator => sub { > return ClassName unless @_; > croak "Param(s) to $name must be valid class name(s)" > if grep { !/$valid_class_re/ } @_; > my @classes = @_; > return sub { > for my $class (@classes) { > return 1 if $_->$belongs_with($class); > } > return; > }; > }; > } > > Though perhaps your way of building a union and then an intersection may > result in nicer error messages when a type check fails. >
> > There is some complication in the declaration since I > > thought it may be a good idea to not have to check against > > ClassName more than once, or does ClassName get checked against > > automatically because of being the parent?
> > Actually with parameterized types, Foo is not automatically the parent > type of Foo[x]. If the constraint generator returns a coderef, then it will > be. But if the constraint generator returns a Type::Tiny object, then the > parameterization process simply respects whatever parent that Type::Tiny > object already has (if any). >
> > (BTW it seems the display_name on the last line never > > kicks in?)
> > The intersection function can be called as either: > > intersection $name, \@constraints; > intersection \@constraints; > > There's no way to pass any additional options. > > There probably should be. Most of the functions in Type::Utils are blindly > borrowed from Moose though, and Moose doesn't. >
> > However I think this may be a common enough need > > to warrant making them standard.
> > I'm reluctant to add much more to Types::Standard itself, simply because > if people import stuff like: > > use Types::Standard qw(:all); > > ... then they're already importing an awful lot of functions. > > I have however recently added Types::Common::Numeric and > Types::Common::String to the distribution, and wouldn't necessarily object > to adding other such modules along the same lines, provided they had decent > test suites, and didn't add any extra dependencies to the distribution. > > Regarding a "ValidClassName" type constraint, you may be interested in > Types::LoadableClass, which has a "ModuleName" constraint. >
I'm not adding these to Types::Standard, but I've added some similar features to Types::LoadableClass 0.003.