Je souhaite créer un type, basé sur la chaîne, qui aura une limite de longueur supérieure et, éventuellement, une limite de longueur inférieure. C'est-à-dire, type paramétré, où la plage de longueur serait un paramètre.
Ce que je veux dans ma mise en œuvre:Type de paramétrage avec un autre type en utilisant Type :: Tiny
- un type distinct pour la gamme de longueur de la chaîne.
- Ne pas utiliser MooseX :: Types ::
- paramétrables Un sucre de paramétrisant type droit avec arrayref, pas hashref:
- Ce:
isa=>Varchar[1, 15]
- Non ceci:
isa=>Varchar[{min=>1, max=>15,}]
- Ce:
Voilà ce que j'ai jusqu'à présent:
Fichier MyTypesTiny.pm
package MyTypesTiny;
use strict;
use warnings;
use Type::Library
-base,
-declare => qw(VarcharRange Varchar);
use Type::Utils -all;
use Types::Standard -types;
use MooseX::Types::Common::Numeric qw(PositiveOrZeroInt);
declare VarcharRange,
as HashRef [PositiveOrZeroInt],
where {
return 0 if (grep { $_ ne 'min' && $_ ne 'max' } keys %{$_});
return ($_->{min} <= $_->{max})
if (defined $_->{max} && defined $_->{min});
return 1;
}, message { "$_" };
coerce VarcharRange, from ArrayRef [PositiveOrZeroInt], via {
my $result;
my @keys = qw(min max);
foreach my $val (reverse @$_) {
my $key = pop @keys // 'bad_range';
$result->{$key} = $val;
}
return $result;
};
1;
Fichier test_varchar.pl
#!/usr/bin/env perl
package MyClass;
use Moose;
use MyTypesTiny qw(VarcharRange);
has 'my_range' => (isa=>VarcharRange, is=>'ro', coerce=>1);
package main;
use MyClass;
my $check = MyClass->new(
my_range => [1, 15], # works, as expected
# my_range => [1, 0], # fails, as expected
# my_range => [0, 1, 2], # fails, as expected
);
Ok, fonctionne VarcharRange. Maintenant, je dois ajouter Varchar lui-même. Et c'est là je suis coincé instantanément:
ajouté à MyTypesTiny.pm:
declare Varchar, as Str, where {}, constraint_generator => sub {
# here I have @_ which is an ArrayRef
# and I want to create a VarcharRange object $range from it
# but what exactly should I do?
return sub {
my $len = length($_);
return 0 if ($range->{min} && $len < $range->{min});
return 0 if ($range->{max} && $len > $range->{max});
return 1;
};
};
Mon cerveau est en ébullition. J'ai mon ArrayRef prêt. Tout ce dont j'ai besoin est un objet VarcharRange (qui est fondamentalement un objet HashRef). Mais VarcharRange est un type - un ensemble de contraintes de nom et de règles de coercition. Cela ne correspond pas à un objet en soi. Les objets pour les types sont créés lorsque les attributs de classe sont créés, mais je n'ai aucune classe en jeu ici.
Vous n'abandonnez pas, n'est-ce pas? : D – simbabque
Je ne vois pas la connexion entre le 'VarcharRange' et le' Varchar'. – simbabque
Voir les lignes commentées dans le code 'Varchar'. Essentiellement, quand je paramétrise 'Varchar' par ArrayRef, je veux en fait, sous le capot, paramétrer' Varchar' par 'VarcharRange' (qui peut être contraint à partir de ArrayRef). – Bob