These keys are LTA
While toying around with enums as boolean options to a routine, i found the default error message less then awesome.
Constraint type check failed for parameter '@options'
It would be hard to be even less specific. Let’s create a few exceptions to tell what is going on when things go wrong.
class X::Paramenter::Exclusive is Exception {
has $.type;
method message {
"Parameters of {$.type.perl} are mutual exclusive"
}
}
Now we can check if options of Find::Type are exclusive and complain accordingly.
&& ( exclusive-argument(@options, Find::Type) or fail X::Paramenter::Exclusive.new(type => Find::Type) )
class X::Parameter::UnrecognisedOption is Exception {
has $.type;
has $.unrecognised;
method message {
"Option { $.unrecognised } not any of { $.type.map({ (.^name ~ '::') xx * Z~ .enums.keys.flat }).flat.join(', ') }"
}
}
Since enums are containers for types and those got names we can use set operators to check and single out none matching options (basically anything the +@options slurps up we don’t know).
or fail X::Parameter::UnrecognisedOption.new(type => (Find::Type, Find::Options),
unrecognised => .item ∖ (|Find::Type::.values, |Find::Options::.values) )
Stitching the error message together is a bit more involved because we can get a list of all enum keys in a given enum but those don’t know their qualified name. We have to prefix with the enum name and :: by hand.
class X::Parameter::UnrecognisedOption is Exception {
has $.type;
has $.unrecognised;
method message {
"Option { $.unrecognised } not any of { $.type.map: { (.^name ~ '::') xx * Z~ .enums.keys.flat } }"
}
}
This results in a much more awesome error message:
Option 42 not any of Type::File, Type::Dir, Type::Symlink, Options::Recursive, Options::Keep-going
This looks all quite regular. We have a slurpy that is kind of parameterised with one or many enums and those enums may have a flag telling if they act like radio buttons. Sounds like this idiom would fit nicely into a module.
-
September 26, 2016 at 23:052016.39 Keys To Cover Moar Tests | Weekly changes in and around Perl 6