Я был сторонником принятия Moose (и MooseX :: Заявляю) на работе несколько месяцев. Стиль, который он поощряет, действительно поможет поддерживать нашу кодовую базу, но не без некоторых начальных затрат на изучение нового синтаксиса, и особенно в изучении того, как анализировать ошибки проверки типов.
Я видел обсуждение в Интернете. об этой проблеме, и подумал, что отправлю в это сообщество запрос о:
a) известных решениях
b) обсуждении того, как должны выглядеть сообщения об ошибках проверки
c) предложить доказательство концепции, которая реализует некоторые идеи
Я также свяжусь с авторами, но я видел хорошие обсуждения и на этом форуме, поэтому решил опубликовать что-нибудь публичное.
#!/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();
Обратите внимание на несоответствие в вызове Foo :: doit с подпись метода.
В результате появляется следующее сообщение об ошибке:
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
Я думаю, что большинство согласны с тем, что это не так прямо, как могло бы быть. Я'
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;
}
[Примечание: после нескольких минут сканирования кода, похоже, что MooseX :: Meta :: TypeConstraint :: Structured :: validate немного ближе к коду, который следует изменить. В любом случае, стоит вопрос об идеальном сообщении об ошибке и о том, активно ли кто-нибудь работает над подобными изменениями или думает о них.]
Что дает 3 вещи:
1) Меньше подробностей, больше пробелов (я обсуждал включение s / Tuple //, но пока придерживаюсь его)
2) Включая вызывающий файл / строку (с хрупким использованием caller (1))
3) умирайте вместо признания - поскольку, как я вижу, Основным преимуществом confess было то, что в любом случае можно было найти точку входа пользователя для проверки типов, чего мы можем добиться менее подробными способами
Конечно, я на самом деле не хочу поддерживать этот патч. У меня вопрос: >> класс (ы) ans = двойной >> класс (ы) == 'двойной' ans = 1 1 1 1 ...
Я получаю действительно странный результат, используя ==
в MATLAB_R2009b на OS X. Пример из подсказки:
s =
2
>> class(s)
ans =
double
>> class(s) == 'double'
ans =
1 1 1 1 1 1
Шесть раз да? Кто-нибудь может это объяснить || предложить решение?