Ich möchte einen Typ, basierend auf der Zeichenfolge, die obere Längengrenze und - optional - untere Längengrenze haben. Das heißt, ein parametrisierter Typ, bei dem der Längenbereich ein Parameter wäre.
Was ich in meiner Implementierung will:Parametrierung Typ mit einem anderen Typ mit Type :: Tiny
- Ein separater Typ für Streichlängenbereich.
- Nicht mit MooseX :: Typen :: parametrierbare
- Ein Zucker von der Art gerade mit ArrayRef Parametrisierung, hashref NICHT:
- Dies:
isa=>Varchar[1, 15]
- Nicht dies:
isa=>Varchar[{min=>1, max=>15,}]
- Dies:
Das habe ich bisher:
Datei 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;
Datei 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, arbeitet VarcharRange. Jetzt muss ich Varchar selbst hinzufügen. Und das ist, wo ich sofort stecken:
hinzugefügt 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;
};
};
Mein Gehirn kocht. Ich habe meine ArrayRef bereit. Alles, was ich brauche, ist ein VarcharRange (was im Grunde ein HashRef-Objekt ist), das daraus gemacht werden soll. Aber VarcharRange ist ein Typ - ein Namenskennzeichnungssatz von Zwangsbedingungen und Zwangsregeln. Es entspricht nicht einem Objekt an sich. Objekte für Typen werden erstellt, wenn Klassenattribute erstellt werden, aber ich habe hier keine Klasse im Spiel.
Sie geben nicht auf, oder? : D – simbabque
Ich sehe keine Verbindung zwischen 'VarcharRange' und' Varchar'. – simbabque
Siehe die kommentierten Zeilen im 'Varchar'-Code. Im Wesentlichen, wenn ich 'Varchar' durch die ArrayRef parametriere, möchte ich eigentlich unter der Haube' Varchar' durch den 'VarcharRange' parametrisieren (der von ArrayRef erzwungen werden kann). – Bob