He sido un defensor de la adopción de Moose (y MooseX :: Declare) en el trabajo durante varios meses. El estilo que fomenta realmente ayudará a la mantenibilidad de nuestra base de código, pero no sin algún costo inicial de aprendizaje de nueva sintaxis, y especialmente al aprender a analizar los errores de validación de tipo.Sucinta MooseX :: Declarar errores de validación de la firma del método
que he visto discusión en línea de este problema, y pensé que había puesto una consulta a esta comunidad para:
a) soluciones conocidas
b) discusión de lo que los mensajes de error de validación debe ser similar
c) proponer una prueba de concepto que implementa algunas ideas
también voy a contactar con los autores, pero he visto alguna buena discusión en este foro también, así que pensé que había puesto algo público.
#!/usr/bin/perl
use MooseX::Declare;
class Foo {
has 'x' => (isa => 'Int', is => 'ro');
method doit(Int $id, Str :$z, Str :$y) {
print "doit called with id = " . $id . "\n";
print "z = " . $z . "\n";
print "y = " . $y . "\n";
}
method bar() {
$self->doit(); # 2, z => 'hello', y => 'there');
}
}
my $foo = Foo->new(x => 4);
$foo->bar();
Tenga en cuenta la falta de coincidencia en la llamada a Foo :: doit con la firma del método.
El mensaje de error que se produce es:
Validation failed for 'MooseX::Types::Structured::Tuple[MooseX::Types::Structured::Tuple[Object,Int],MooseX::Types::Structured::Dict[z,MooseX::Types::Structured::Optional[Str],y,MooseX::Types::Structured::Optional[Str]]]' failed with value [ [ Foo=HASH(0x2e02dd0) ], { } ], Internal Validation Error is: Validation failed for 'MooseX::Types::Structured::Tuple[Object,Int]' failed with value [ Foo{ x: 4 } ] at /usr/local/share/perl/5.10.0/MooseX/Method/Signatures/Meta/Method.pm line 441
MooseX::Method::Signatures::Meta::Method::validate('MooseX::Method::Signatures::Meta::Method=HASH(0x2ed9dd0)', 'ARRAY(0x2eb8b28)') called at /usr/local/share/perl/5.10.0/MooseX/Method/Signatures/Meta/Method.pm line 145
Foo::doit('Foo=HASH(0x2e02dd0)') called at ./type_mismatch.pl line 15
Foo::bar('Foo=HASH(0x2e02dd0)') called at ./type_mismatch.pl line 20
creo que la mayoría de acuerdo en que esto no es tan directa como podría ser. He implementado un corte en mi copia local de MooseX :: Método Método :: Firmas :: :: Meta que produce esta salida para el mismo programa:
Validation failed for
'[[Object,Int],Dict[z,Optional[Str],y,Optional[Str]]]' failed with value [ [ Foo=HASH(0x1c97d48) ], { } ]
Internal Validation Error:
'[Object,Int]' failed with value [ Foo{ x: 4 } ]
Caller: ./type_mismatch.pl line 15 (package Foo, subroutine Foo::doit)
El código super-hacky que hace esto es
if (defined (my $msg = $self->type_constraint->validate($args, \$coerced))) {
if($msg =~ /MooseX::Types::Structured::/) {
$msg =~ s/MooseX::Types::Structured:://g;
$msg =~ s/,.Internal/\n\nInternal/;
$msg =~ s/failed.for./failed for\n\n /g;
$msg =~ s/Tuple//g;
$msg =~ s/ is: Validation failed for/:/;
}
my ($pkg, $filename, $lineno, $subroutine) = caller(1);
$msg .= "\n\nCaller: $filename line $lineno (package $pkg, subroutine $subroutine)\n";
die $msg;
}
[Nota: con unos pocos minutos más de rastrear el código, parece que MooseX :: :: Meta TypeConstraint :: :: estructurado de validación es un poco más cerca del código que debe ser cambiado. En cualquier caso, la pregunta sobre el mensaje de error ideales, y si alguien está trabajando activamente en o pensando en cambios similares se destaca]
que lleva a cabo 3 cosas:.
1) Menos detallado, más espacios en blanco (debatí incluyendo s/tupla //, pero la que mantiene con ella por ahora)
2) incluyendo llamando archivo/línea (con el uso frágil de la persona que llama (1))
3) morir en lugar de confesar - ya que como Veo que la principal ventaja de confess fue encontrar el punto de entrada del usuario en la verificación de tipo de todos modos, lo que podemos lograr en w menos detallado ays
Por supuesto que en realidad no quiero apoyar este parche. Mi pregunta es: ¿cuál es la mejor manera de equilibrar la integridad y la brevedad de estos mensajes de error, y hay planes actuales para poner algo así en su lugar?
Gracias, eso es realmente útil.Aunque ahora mi pregunta es: 1) ¿cuál es la forma de Moose-y de lanzar excepciones estructuradas como esa, y 2) si eso es demasiado problema sería más fácil factorizar la validación de tipo para no usar excepciones para denotar la falla de validación? Estaré encantado de ayudar con el proyecto, cualquiera que sea la solución ideal. ¿Cuánto trabajo crees que sería? Me gusta su formato de mensaje de error propuesto. Realmente ayudaría a un grupo como el mío a alcanzar la máxima velocidad con MooseX :: Declare. –
@adamp: Un lugar donde se crean excepciones estructuradas de Moose está en MooseX :: Constructor :: AllErrors: esta sería otra fuente de ideas sobre cómo resolver el problema de "Las excepciones de los alces deben ser objetos" de una manera más universal . – Ether
@ether: Gracias por el consejo. Echaré un vistazo a MooseX :: Constructor :: AllErrors para tener una idea de cómo deben crearse y arrojarse estos errores de validación. –